[tomcat] branch master updated: Filter out classes streams through class file transformers

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[tomcat] branch master updated: Filter out classes streams through class file transformers

remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ef6875  Filter out classes streams through class file transformers
6ef6875 is described below

commit 6ef68752dc43f9d459e0ae23a4a767112ab531b9
Author: remm <[hidden email]>
AuthorDate: Wed Feb 17 16:46:41 2021 +0100

    Filter out classes streams through class file transformers
   
    Make getResourceAsStream go through the ClassFileTransformer(s) for
    .class resources. In a way this is consistent, but the actual reason is
    helping JSP work better [JDT uses that to do its compilation] if
    choosing a very basic runtime Jakarta conversion. I'm not seeing any
    basis for doing it, but it's completely unlikely to break anything
    either.
---
 .../catalina/loader/WebappClassLoaderBase.java     | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index 2bc07a1..d809c3e 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -16,6 +16,8 @@
  */
 package org.apache.catalina.loader;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FilePermission;
 import java.io.IOException;
@@ -1136,6 +1138,41 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
         WebResource resource = resources.getClassLoaderResource(path);
         if (resource.exists()) {
             stream = resource.getInputStream();
+            // Filter out .class resources through the ClassFileTranformer
+            if (name.endsWith(".class") && transformers.size() > 0) {
+                // If the resource is a class, decorate it with any attached transformers
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                byte[] buf = new byte[8192];
+                int numRead;
+                try {
+                    while ((numRead = stream.read(buf)) >= 0) {
+                        baos.write(buf, 0, numRead);
+                    }
+                } catch (IOException e) {
+                    log.error(sm.getString("webappClassLoader.transformError", name), e);
+                    return null;
+                } finally {
+                    try {
+                        stream.close();
+                    } catch (IOException e) {
+                    }
+                }
+                byte[] binaryContent = baos.toByteArray();
+                String internalName = path.substring(1, path.length() - CLASS_FILE_SUFFIX.length());
+                for (ClassFileTransformer transformer : this.transformers) {
+                    try {
+                        byte[] transformed = transformer.transform(
+                                this, internalName, null, null, binaryContent);
+                        if (transformed != null) {
+                            binaryContent = transformed;
+                        }
+                    } catch (IllegalClassFormatException e) {
+                        log.error(sm.getString("webappClassLoader.transformError", name), e);
+                        return null;
+                    }
+                }
+                stream = new ByteArrayInputStream(binaryContent);
+            }
             trackLastModified(path, resource);
         }
         try {


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [tomcat] branch master updated: Filter out classes streams through class file transformers

Martin Grigorov
On Wed, Feb 17, 2021 at 5:49 PM <[hidden email]> wrote:

> This is an automated email from the ASF dual-hosted git repository.
>
> remm pushed a commit to branch master
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
>
>
> The following commit(s) were added to refs/heads/master by this push:
>      new 6ef6875  Filter out classes streams through class file
> transformers
> 6ef6875 is described below
>
> commit 6ef68752dc43f9d459e0ae23a4a767112ab531b9
> Author: remm <[hidden email]>
> AuthorDate: Wed Feb 17 16:46:41 2021 +0100
>
>     Filter out classes streams through class file transformers
>
>     Make getResourceAsStream go through the ClassFileTransformer(s) for
>     .class resources. In a way this is consistent, but the actual reason is
>     helping JSP work better [JDT uses that to do its compilation] if
>     choosing a very basic runtime Jakarta conversion. I'm not seeing any
>     basis for doing it, but it's completely unlikely to break anything
>     either.
> ---
>  .../catalina/loader/WebappClassLoaderBase.java     | 37
> ++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
>
> diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
> b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
> index 2bc07a1..d809c3e 100644
> --- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
> +++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
> @@ -16,6 +16,8 @@
>   */
>  package org.apache.catalina.loader;
>
> +import java.io.ByteArrayInputStream;
> +import java.io.ByteArrayOutputStream;
>  import java.io.File;
>  import java.io.FilePermission;
>  import java.io.IOException;
> @@ -1136,6 +1138,41 @@ public abstract class WebappClassLoaderBase extends
> URLClassLoader
>          WebResource resource = resources.getClassLoaderResource(path);
>          if (resource.exists()) {
>              stream = resource.getInputStream();
> +            // Filter out .class resources through the ClassFileTranformer
> +            if (name.endsWith(".class") && transformers.size() > 0) {
>

nit: you could use CLASS_FILE_SUFFIX as you did below


> +                // If the resource is a class, decorate it with any
> attached transformers
> +                ByteArrayOutputStream baos = new ByteArrayOutputStream();
> +                byte[] buf = new byte[8192];
> +                int numRead;
> +                try {
> +                    while ((numRead = stream.read(buf)) >= 0) {
> +                        baos.write(buf, 0, numRead);
> +                    }
> +                } catch (IOException e) {
> +
> log.error(sm.getString("webappClassLoader.transformError", name), e);
> +                    return null;
> +                } finally {
> +                    try {
> +                        stream.close();
> +                    } catch (IOException e) {
> +                    }
> +                }
> +                byte[] binaryContent = baos.toByteArray();
> +                String internalName = path.substring(1, path.length() -
> CLASS_FILE_SUFFIX.length());
> +                for (ClassFileTransformer transformer :
> this.transformers) {
> +                    try {
> +                        byte[] transformed = transformer.transform(
> +                                this, internalName, null, null,
> binaryContent);
> +                        if (transformed != null) {
> +                            binaryContent = transformed;
> +                        }
> +                    } catch (IllegalClassFormatException e) {
> +
> log.error(sm.getString("webappClassLoader.transformError", name), e);
> +                        return null;
> +                    }
> +                }
> +                stream = new ByteArrayInputStream(binaryContent);
> +            }
>              trackLastModified(path, resource);
>          }
>          try {
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>