You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2019/06/18 08:50:08 UTC

[sling-whiteboard] branch feature/jmx created (now 4c72894)

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

rombert pushed a change to branch feature/jmx
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git.


      at 4c72894  Simplify child classes by passing a CtClass instance instead of a class name

This branch includes the following new commits:

     new 6cf61fd  Expose runtime information through JMX
     new e17e71c  Add a support class for JMX
     new 4c72894  Simplify child classes by passing a CtClass instance instead of a class name

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-whiteboard] 01/03: Expose runtime information through JMX

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch feature/jmx
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit 6cf61fd03cb8d1eb09aadf09f6846fb680a4cd32
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Jun 18 10:26:43 2019 +0200

    Expose runtime information through JMX
---
 .../main/java/org/apache/sling/uca/impl/Agent.java | 28 ++++++--
 .../java/org/apache/sling/uca/impl/AgentInfo.java  | 77 ++++++++++++++++++++++
 ...TimeoutTransformer.java => AgentInfoMBean.java} | 42 ++++++++----
 .../uca/impl/HttpClient3TimeoutTransformer.java    |  7 +-
 .../uca/impl/HttpClient4TimeoutTransformer.java    |  4 +-
 .../sling/uca/impl/JavaNetTimeoutTransformer.java  |  7 +-
 .../sling/uca/impl/OkHttpTimeoutTransformer.java   |  4 +-
 ...pdateFieldsInConstructorTimeoutTransformer.java |  6 +-
 .../uca/impl/JaveNetTimeoutTransformerTest.java    |  2 +-
 9 files changed, 151 insertions(+), 26 deletions(-)

diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
index 3842268..d46c56c 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/Agent.java
@@ -18,8 +18,15 @@ package org.apache.sling.uca.impl;
 
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.Instrumentation;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.NotCompliantMBeanException;
+
 public class Agent {
 
     public static void premain(String args, Instrumentation inst) {
@@ -39,15 +46,26 @@ public class Agent {
         
         Log.get().log("Preparing to install URL transformers. Configured timeouts - connectTimeout : %d, readTimeout: %d", connectTimeout, readTimeout);
 
+        AgentInfo agentInfoMBean = new AgentInfo(connectTimeout, readTimeout);
+        
         ClassFileTransformer[] transformers = new ClassFileTransformer[] {
-            new JavaNetTimeoutTransformer(connectTimeout, readTimeout),
-            new HttpClient3TimeoutTransformer(connectTimeout, readTimeout),
-            new HttpClient4TimeoutTransformer(connectTimeout, readTimeout),
-            new OkHttpTimeoutTransformer(connectTimeout, readTimeout)
+            new JavaNetTimeoutTransformer(connectTimeout, readTimeout, agentInfoMBean),
+            new HttpClient3TimeoutTransformer(connectTimeout, readTimeout, agentInfoMBean),
+            new HttpClient4TimeoutTransformer(connectTimeout, readTimeout, agentInfoMBean),
+            new OkHttpTimeoutTransformer(connectTimeout, readTimeout, agentInfoMBean)
         };
         
-        for ( ClassFileTransformer transformer : transformers )
+        List<String> transformerNames = new ArrayList<>();
+        for ( ClassFileTransformer transformer : transformers ) {
             inst.addTransformer(transformer, true);
+            transformerNames.add(transformer.getClass().getName());
+        }
+        
+        try {
+            ManagementFactory.getPlatformMBeanServer().registerMBean(agentInfoMBean, AgentInfo.NAME);
+        } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
+            Log.get().log("Failed registering MBean: %s", e.getMessage());
+        }
 
         Log.get().log("All transformers installed");
     }    
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/AgentInfo.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/AgentInfo.java
new file mode 100644
index 0000000..1a4f641
--- /dev/null
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/AgentInfo.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.uca.impl;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+public class AgentInfo implements AgentInfoMBean {
+    
+    static final ObjectName NAME;
+    
+    static {
+        try {
+            NAME = new ObjectName(AgentInfo.class.getPackage().getName()+":type=Agent");
+        } catch (MalformedObjectNameException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+    
+    private final long connectTimeoutMillis;
+    
+    private final long readTimeoutMillis;
+
+    private List<String> transformers = new ArrayList<>();
+
+    private List<String> transformedClasses = new ArrayList<>();
+    
+
+    public AgentInfo(long connectTimeoutMillis, long readTimeoutMillis) {
+        this.connectTimeoutMillis = connectTimeoutMillis;
+        this.readTimeoutMillis = readTimeoutMillis;
+    }
+
+    @Override
+    public long getConnectTimeoutMillis() {
+        return connectTimeoutMillis;
+    }
+
+    @Override
+    public long getReadTimeoutMillis() {
+        return readTimeoutMillis;
+    }
+    
+    public String[] getTransformers() {
+        return transformers.toArray(new String[0]);
+    }
+    
+    public String[] getTransformedClasses() {
+        return transformedClasses.toArray(new String[0]);
+    }
+    
+    public void registerTransformedClass(String transformedClassName) {
+        transformedClasses.add(transformedClassName);
+    }
+    
+    public void registerTransformer(Class<? extends ClassFileTransformer> transformerClass) {
+        transformers.add(transformerClass.getName());
+    }
+}
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/OkHttpTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/AgentInfoMBean.java
similarity index 53%
copy from url-connection-agent/src/main/java/org/apache/sling/uca/impl/OkHttpTimeoutTransformer.java
copy to url-connection-agent/src/main/java/org/apache/sling/uca/impl/AgentInfoMBean.java
index bcfae7c..d0b9eb9 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/OkHttpTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/AgentInfoMBean.java
@@ -16,21 +16,37 @@
  */
 package org.apache.sling.uca.impl;
 
-import javassist.bytecode.Descriptor;
-
 /**
- * Sets timeouts for HTTP calls done using <em>OkHttp 3.x</em>
- * 
- * <p>It inserts two calls to <tt>okhttp3.OkHttpClient$Builder</tt> that set default
- * values for <tt>connectTimeout</tt> and <tt>readTimeout</tt>.</p>
+ * Exposes runtime information about the agent using <tt>JMX</tt>.
+ *
  */
-public class OkHttpTimeoutTransformer extends UpdateFieldsInConstructorTimeoutTransformer {
+public interface AgentInfoMBean {
 
-    private static final String REQUEST_CONFIG_BUILDER_CLASS_NAME = Descriptor.toJvmName("okhttp3.OkHttpClient$Builder");
+    /**
+     * Returns the connect timeout
+     * 
+     * @return the connect timeout as configured, in milliseconds
+     */
+    long getConnectTimeoutMillis();
+
+    /**
+     * Returns the read timeout
+     * 
+     * @return the read timeout as configured, in milliseconds
+     */
+    long getReadTimeoutMillis();
+    
+    /**
+     * Returns the active transformers
+     * 
+     * @return the active transformers
+     */
+    String[] getTransformers();
     
-    public OkHttpTimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis) {
-        
-        super(REQUEST_CONFIG_BUILDER_CLASS_NAME, "connectTimeout", "readTimeout", 
-            connectTimeoutMillis, readTimeoutMillis);
-    }
+    /**
+     * Returns the classes that were transformed to enforce global timeout defaults
+     * 
+     * @return the classes that were transformed
+     */
+    String[] getTransformedClasses();
 }
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
index 9bf5d92..05e2891 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
@@ -37,10 +37,13 @@ public class HttpClient3TimeoutTransformer implements ClassFileTransformer {
     
     private final long connectTimeoutMillis;
     private final long readTimeoutMillis;
+    private final AgentInfo agentInfoMbean;
     
-    public HttpClient3TimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis) {
+    public HttpClient3TimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfoMBean) {
         this.connectTimeoutMillis = connectTimeoutMillis;
         this.readTimeoutMillis = readTimeoutMillis;
+        this.agentInfoMbean = agentInfoMBean;
+        this.agentInfoMbean.registerTransformer(getClass());
     }
 
     @Override
@@ -64,6 +67,8 @@ public class HttpClient3TimeoutTransformer implements ClassFileTransformer {
                 classfileBuffer = cc.toBytecode();
                 cc.detach();
                 Log.get().log("Transformation complete.");
+                
+                agentInfoMbean.registerTransformedClass(className);
             }
             return classfileBuffer;
         } catch (Exception e) {
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
index 5b5b317..6a3990a 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
@@ -30,8 +30,8 @@ public class HttpClient4TimeoutTransformer extends UpdateFieldsInConstructorTime
     
     private static final String REQUEST_CONFIG_BUILDER_CLASS_NAME = Descriptor.toJvmName("org.apache.http.client.config.RequestConfig$Builder");
     
-    public HttpClient4TimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis) {
+    public HttpClient4TimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfoMBean) {
         super(REQUEST_CONFIG_BUILDER_CLASS_NAME, "connectTimeout", "socketTimeout",
-            connectTimeoutMillis, readTimeoutMillis);
+            connectTimeoutMillis, readTimeoutMillis, agentInfoMBean);
     }
 }
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
index 121417c..02e07f3 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
@@ -49,10 +49,13 @@ class JavaNetTimeoutTransformer implements ClassFileTransformer {
 
     private final long readTimeoutMillis;
     private final long connectTimeoutMillis;
+    private final AgentInfo agentInfoMBean;
 
-    public JavaNetTimeoutTransformer(long connectTimeout, long readTimeout) {
+    public JavaNetTimeoutTransformer(long connectTimeout, long readTimeout, AgentInfo agentInfoMBean) {
         this.connectTimeoutMillis = connectTimeout;
         this.readTimeoutMillis = readTimeout;
+        this.agentInfoMBean = agentInfoMBean;
+        this.agentInfoMBean.registerTransformer(getClass());
     }
 
     @Override
@@ -67,6 +70,8 @@ class JavaNetTimeoutTransformer implements ClassFileTransformer {
                 classfileBuffer = connectMethod.getDeclaringClass().toBytecode();
                 connectMethod.getDeclaringClass().detach();
                 Log.get().log("Transformation complete.");
+                
+                this.agentInfoMBean.registerTransformedClass(className);
             }
             return classfileBuffer;
         } catch (Exception e) {
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/OkHttpTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/OkHttpTimeoutTransformer.java
index bcfae7c..458996e 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/OkHttpTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/OkHttpTimeoutTransformer.java
@@ -28,9 +28,9 @@ public class OkHttpTimeoutTransformer extends UpdateFieldsInConstructorTimeoutTr
 
     private static final String REQUEST_CONFIG_BUILDER_CLASS_NAME = Descriptor.toJvmName("okhttp3.OkHttpClient$Builder");
     
-    public OkHttpTimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis) {
+    public OkHttpTimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfoMBean) {
         
         super(REQUEST_CONFIG_BUILDER_CLASS_NAME, "connectTimeout", "readTimeout", 
-            connectTimeoutMillis, readTimeoutMillis);
+            connectTimeoutMillis, readTimeoutMillis, agentInfoMBean);
     }
 }
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
index 274bcd4..1ed23e9 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
@@ -36,15 +36,18 @@ public abstract class UpdateFieldsInConstructorTimeoutTransformer implements Cla
     private final String readTimeoutFieldName;
     private final long connectTimeoutMillis;
     private final long readTimeoutMillis;
+    private final AgentInfo agentInfoMBean;
 
     public UpdateFieldsInConstructorTimeoutTransformer(String className, String connectTimeoutFieldName,
-            String readTimeoutFieldName, long connectTimeoutMillis, long readTimeoutMillis) {
+            String readTimeoutFieldName, long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfoMBean) {
 
         this.className = className;
         this.connectTimeoutFieldName = connectTimeoutFieldName;
         this.readTimeoutFieldName = readTimeoutFieldName;
         this.connectTimeoutMillis = connectTimeoutMillis;
         this.readTimeoutMillis = readTimeoutMillis;
+        this.agentInfoMBean = agentInfoMBean;
+        this.agentInfoMBean.registerTransformer(getClass());
     }
 
     @Override
@@ -66,6 +69,7 @@ public abstract class UpdateFieldsInConstructorTimeoutTransformer implements Cla
                 classfileBuffer = cc.toBytecode();
                 cc.detach();
                 Log.get().log("Transformation complete.");
+                this.agentInfoMBean.registerTransformedClass(className);
             }
             return classfileBuffer;
         } catch (Exception e) {
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/JaveNetTimeoutTransformerTest.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/JaveNetTimeoutTransformerTest.java
index c0abffc..9ddffde 100644
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/JaveNetTimeoutTransformerTest.java
+++ b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/JaveNetTimeoutTransformerTest.java
@@ -31,7 +31,7 @@ public class JaveNetTimeoutTransformerTest {
 
     @BeforeEach
     public void initFields() {
-        transformer = new JavaNetTimeoutTransformer(1, 1);
+        transformer = new JavaNetTimeoutTransformer(1, 1, new AgentInfo(1, 1));
     }
 
     @Test


[sling-whiteboard] 02/03: Add a support class for JMX

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch feature/jmx
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit e17e71c4add8782cedfec443f99f16cf857f4eff
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Jun 18 10:40:03 2019 +0200

    Add a support class for JMX
---
 .../uca/impl/HttpClient3TimeoutTransformer.java    | 56 ++++++++------------
 .../sling/uca/impl/JavaNetTimeoutTransformer.java  | 42 +++++----------
 .../uca/impl/MBeanAwareTimeoutTransformer.java     | 59 ++++++++++++++++++++++
 ...pdateFieldsInConstructorTimeoutTransformer.java | 57 ++++++++-------------
 4 files changed, 114 insertions(+), 100 deletions(-)

diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
index 05e2891..e4da3ec 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
@@ -16,9 +16,7 @@
  */
 package org.apache.sling.uca.impl;
 
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.security.ProtectionDomain;
+import java.util.Collections;
 
 import javassist.ClassPool;
 import javassist.CtClass;
@@ -31,49 +29,37 @@ import javassist.bytecode.Descriptor;
  * <p>It inserts two calls in <tt>org.apache.commons.httpclient.params.DefaultHttpParamsFactory.createParams</tt> that set
  * default values for <tt>http.connection.timeout</tt> and <tt>http.socket.timeout</tt>.</p>
  */
-public class HttpClient3TimeoutTransformer implements ClassFileTransformer {
+public class HttpClient3TimeoutTransformer extends MBeanAwareTimeoutTransformer {
     
     private static final String DEFAULT_HTTP_PARAMS_FACTORY_CLASS_NAME = Descriptor.toJvmName("org.apache.commons.httpclient.params.DefaultHttpParamsFactory");
     
     private final long connectTimeoutMillis;
     private final long readTimeoutMillis;
-    private final AgentInfo agentInfoMbean;
     
     public HttpClient3TimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfoMBean) {
+        super(agentInfoMBean, Collections.singleton(DEFAULT_HTTP_PARAMS_FACTORY_CLASS_NAME));
         this.connectTimeoutMillis = connectTimeoutMillis;
         this.readTimeoutMillis = readTimeoutMillis;
-        this.agentInfoMbean = agentInfoMBean;
-        this.agentInfoMbean.registerTransformer(getClass());
     }
 
     @Override
-    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
-            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
-        try {
-            if ( DEFAULT_HTTP_PARAMS_FACTORY_CLASS_NAME.equals(className) ) {
-                Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
-                
-                ClassPool defaultPool = ClassPool.getDefault();
-                CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
-                
-                CtMethod getSoTimeout =  cc.getDeclaredMethod("createParams");
-                // javassist seems unable to resolve the constant values, so just inline them
-                // also, unable to resolve calls to setParameter with int values (no boxing?)
-                // HttpConnectionParams.CONNECTION_TIMEOUT
-                getSoTimeout.insertAfter("$_.setParameter(\"http.connection.timeout\", Integer.valueOf(" + connectTimeoutMillis + "));");
-                // HttpMethodParams.SO_TIMEOUT
-                getSoTimeout.insertAfter("$_.setParameter(\"http.socket.timeout\", Integer.valueOf(" + readTimeoutMillis + "));");
-                
-                classfileBuffer = cc.toBytecode();
-                cc.detach();
-                Log.get().log("Transformation complete.");
-                
-                agentInfoMbean.registerTransformedClass(className);
-            }
-            return classfileBuffer;
-        } catch (Exception e) {
-            Log.get().fatal("Transformation failed", e);
-            return null;
-        }
+    protected byte[] doTransformClass(String className) throws Exception {
+        
+        ClassPool defaultPool = ClassPool.getDefault();
+        CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
+        
+        CtMethod getSoTimeout =  cc.getDeclaredMethod("createParams");
+        // javassist seems unable to resolve the constant values, so just inline them
+        // also, unable to resolve calls to setParameter with int values (no boxing?)
+        // HttpConnectionParams.CONNECTION_TIMEOUT
+        getSoTimeout.insertAfter("$_.setParameter(\"http.connection.timeout\", Integer.valueOf(" + connectTimeoutMillis + "));");
+        // HttpMethodParams.SO_TIMEOUT
+        getSoTimeout.insertAfter("$_.setParameter(\"http.socket.timeout\", Integer.valueOf(" + readTimeoutMillis + "));");
+        
+        byte[] classfileBuffer = cc.toBytecode();
+        cc.detach();
+        
+        return classfileBuffer;
     }
+
 }
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
index 02e07f3..4dfcf89 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
@@ -16,9 +16,7 @@
  */
 package org.apache.sling.uca.impl;
 
-import java.lang.instrument.ClassFileTransformer;
 import java.net.URLConnection;
-import java.security.ProtectionDomain;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -38,9 +36,9 @@ import javassist.bytecode.Descriptor;
  * @see URLConnection#getReadTimeout()
  *
  */
-class JavaNetTimeoutTransformer implements ClassFileTransformer {
+class JavaNetTimeoutTransformer extends MBeanAwareTimeoutTransformer {
 
-    private static final Set<String> CLASSES_TO_TRANSFORM = new HashSet<>();
+    static final Set<String> CLASSES_TO_TRANSFORM = new HashSet<>();
 
     static {
         CLASSES_TO_TRANSFORM.add(Descriptor.toJvmName("sun.net.www.protocol.http.HttpURLConnection"));
@@ -49,35 +47,21 @@ class JavaNetTimeoutTransformer implements ClassFileTransformer {
 
     private final long readTimeoutMillis;
     private final long connectTimeoutMillis;
-    private final AgentInfo agentInfoMBean;
-
-    public JavaNetTimeoutTransformer(long connectTimeout, long readTimeout, AgentInfo agentInfoMBean) {
+    public JavaNetTimeoutTransformer(long connectTimeout, long readTimeout, AgentInfo agentInfo) {
+        
+        super(agentInfo, CLASSES_TO_TRANSFORM);
+        
         this.connectTimeoutMillis = connectTimeout;
         this.readTimeoutMillis = readTimeout;
-        this.agentInfoMBean = agentInfoMBean;
-        this.agentInfoMBean.registerTransformer(getClass());
     }
 
-    @Override
-    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
-            ProtectionDomain protectionDomain, byte[] classfileBuffer) {
-        try {
-            if (CLASSES_TO_TRANSFORM.contains(className)) {
-                Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
-                CtMethod connectMethod = findConnectMethod(className);
-                connectMethod.insertBefore("if ( getConnectTimeout() == 0 ) { setConnectTimeout(" + connectTimeoutMillis + "); }");
-                connectMethod.insertBefore("if ( getReadTimeout() == 0 ) { setReadTimeout(" + readTimeoutMillis + "); }");
-                classfileBuffer = connectMethod.getDeclaringClass().toBytecode();
-                connectMethod.getDeclaringClass().detach();
-                Log.get().log("Transformation complete.");
-                
-                this.agentInfoMBean.registerTransformedClass(className);
-            }
-            return classfileBuffer;
-        } catch (Exception e) {
-            Log.get().fatal("Transformation failed", e);
-            return null;
-        }
+    protected byte[] doTransformClass(String className) throws Exception {
+        CtMethod connectMethod = findConnectMethod(className);
+        connectMethod.insertBefore("if ( getConnectTimeout() == 0 ) { setConnectTimeout(" + connectTimeoutMillis + "); }");
+        connectMethod.insertBefore("if ( getReadTimeout() == 0 ) { setReadTimeout(" + readTimeoutMillis + "); }");
+        byte[] classfileBuffer = connectMethod.getDeclaringClass().toBytecode();
+        connectMethod.getDeclaringClass().detach();
+        return classfileBuffer;
     }
     
     CtMethod findConnectMethod(String className) throws NotFoundException {
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/MBeanAwareTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/MBeanAwareTimeoutTransformer.java
new file mode 100644
index 0000000..8211457
--- /dev/null
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/MBeanAwareTimeoutTransformer.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.uca.impl;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.security.ProtectionDomain;
+import java.util.Set;
+
+/**
+ * Support class for transformers that expose runtime information through JMX
+ * 
+ * <p>All transformer implementations should extend from this base class.</p>
+ *
+ */
+public abstract class MBeanAwareTimeoutTransformer implements ClassFileTransformer {
+
+    private final AgentInfo agentInfo;
+    private final Set<String> classesToTransform;
+
+    public MBeanAwareTimeoutTransformer(AgentInfo agent, Set<String> classesToTransform) {
+        this.agentInfo = agent;
+        this.classesToTransform = classesToTransform;
+        this.agentInfo.registerTransformer(getClass());
+    }
+
+    @Override
+    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
+        try {
+            if (classesToTransform.contains(className)) {
+                Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
+                classfileBuffer = doTransformClass(className);
+                Log.get().log("Transformation complete.");
+                
+                this.agentInfo.registerTransformedClass(className);
+            }
+            return classfileBuffer;
+        } catch (Exception e) {
+            Log.get().fatal("Transformation failed", e);
+            return null;
+        }
+    }
+
+    protected abstract byte[] doTransformClass(String className) throws Exception;
+
+}
\ No newline at end of file
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
index 1ed23e9..77ed113 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
@@ -16,9 +16,7 @@
  */
 package org.apache.sling.uca.impl;
 
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.security.ProtectionDomain;
+import java.util.Collections;
 
 import javassist.ClassPool;
 import javassist.CtClass;
@@ -29,52 +27,39 @@ import javassist.bytecode.Descriptor;
 /**
  * Support class for transformers that update the timeout fields in the default constructor
  */
-public abstract class UpdateFieldsInConstructorTimeoutTransformer implements ClassFileTransformer {
+public abstract class UpdateFieldsInConstructorTimeoutTransformer extends MBeanAwareTimeoutTransformer {
 
-    private final String className;
     private final String connectTimeoutFieldName;
     private final String readTimeoutFieldName;
     private final long connectTimeoutMillis;
     private final long readTimeoutMillis;
-    private final AgentInfo agentInfoMBean;
 
     public UpdateFieldsInConstructorTimeoutTransformer(String className, String connectTimeoutFieldName,
-            String readTimeoutFieldName, long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfoMBean) {
+            String readTimeoutFieldName, long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfo) {
 
-        this.className = className;
+        super(agentInfo, Collections.singleton(className));
+        
         this.connectTimeoutFieldName = connectTimeoutFieldName;
         this.readTimeoutFieldName = readTimeoutFieldName;
         this.connectTimeoutMillis = connectTimeoutMillis;
         this.readTimeoutMillis = readTimeoutMillis;
-        this.agentInfoMBean = agentInfoMBean;
-        this.agentInfoMBean.registerTransformer(getClass());
     }
-
+    
     @Override
-    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
-            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
-        try {
-            if ( this.className.equals(className) ) {
-                Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
-                
-                ClassPool defaultPool = ClassPool.getDefault();
-                CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
-                
-                CtConstructor noArgCtor = cc.getConstructor(Descriptor.ofConstructor(new CtClass[0]));
-                CtField connectTimeout = cc.getDeclaredField(connectTimeoutFieldName);
-                CtField readTimeout = cc.getDeclaredField(readTimeoutFieldName);
-                noArgCtor.insertAfter("this." + connectTimeout.getName() + " = " + connectTimeoutMillis + ";");
-                noArgCtor.insertAfter("this." + readTimeout.getName() + " = " + readTimeoutMillis + ";");
-                
-                classfileBuffer = cc.toBytecode();
-                cc.detach();
-                Log.get().log("Transformation complete.");
-                this.agentInfoMBean.registerTransformedClass(className);
-            }
-            return classfileBuffer;
-        } catch (Exception e) {
-            Log.get().fatal("Transformation failed", e);
-            return null;
-        }
+    protected byte[] doTransformClass(String className) throws Exception {
+        ClassPool defaultPool = ClassPool.getDefault();
+        CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
+        
+        CtConstructor noArgCtor = cc.getConstructor(Descriptor.ofConstructor(new CtClass[0]));
+        CtField connectTimeout = cc.getDeclaredField(connectTimeoutFieldName);
+        CtField readTimeout = cc.getDeclaredField(readTimeoutFieldName);
+        noArgCtor.insertAfter("this." + connectTimeout.getName() + " = " + connectTimeoutMillis + ";");
+        noArgCtor.insertAfter("this." + readTimeout.getName() + " = " + readTimeoutMillis + ";");
+        
+        byte[] classfileBuffer = cc.toBytecode();
+        cc.detach();
+        
+        return classfileBuffer;
     }
+
 }


[sling-whiteboard] 03/03: Simplify child classes by passing a CtClass instance instead of a class name

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch feature/jmx
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit 4c72894e5f010ca2bdeda0cb3a3e83be28936b98
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Jun 18 10:49:22 2019 +0200

    Simplify child classes by passing a CtClass instance instead of a class name
    
    This also leads to removing a test class since the code it was testing became a one-liner.
---
 .../uca/impl/HttpClient3TimeoutTransformer.java    |  6 +--
 .../uca/impl/HttpClient4TimeoutTransformer.java    |  2 -
 .../sling/uca/impl/JavaNetTimeoutTransformer.java  | 18 +-------
 .../uca/impl/MBeanAwareTimeoutTransformer.java     | 26 ++++++++---
 ...pdateFieldsInConstructorTimeoutTransformer.java |  5 +--
 .../uca/impl/JaveNetTimeoutTransformerTest.java    | 51 ----------------------
 6 files changed, 25 insertions(+), 83 deletions(-)

diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
index e4da3ec..aa0b807 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient3TimeoutTransformer.java
@@ -18,7 +18,6 @@ package org.apache.sling.uca.impl;
 
 import java.util.Collections;
 
-import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.CtMethod;
 import javassist.bytecode.Descriptor;
@@ -43,10 +42,7 @@ public class HttpClient3TimeoutTransformer extends MBeanAwareTimeoutTransformer
     }
 
     @Override
-    protected byte[] doTransformClass(String className) throws Exception {
-        
-        ClassPool defaultPool = ClassPool.getDefault();
-        CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
+    protected byte[] doTransformClass(CtClass cc) throws Exception {
         
         CtMethod getSoTimeout =  cc.getDeclaredMethod("createParams");
         // javassist seems unable to resolve the constant values, so just inline them
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
index 6a3990a..f888936 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/HttpClient4TimeoutTransformer.java
@@ -26,8 +26,6 @@ import javassist.bytecode.Descriptor;
  */
 public class HttpClient4TimeoutTransformer extends UpdateFieldsInConstructorTimeoutTransformer {
 
-    // org.apache.http.client.config.RequestConfig.Builder
-    
     private static final String REQUEST_CONFIG_BUILDER_CLASS_NAME = Descriptor.toJvmName("org.apache.http.client.config.RequestConfig$Builder");
     
     public HttpClient4TimeoutTransformer(long connectTimeoutMillis, long readTimeoutMillis, AgentInfo agentInfoMBean) {
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
index 4dfcf89..2e5654b 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/JavaNetTimeoutTransformer.java
@@ -20,10 +20,8 @@ import java.net.URLConnection;
 import java.util.HashSet;
 import java.util.Set;
 
-import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.CtMethod;
-import javassist.NotFoundException;
 import javassist.bytecode.Descriptor;
 
 /**
@@ -55,25 +53,13 @@ class JavaNetTimeoutTransformer extends MBeanAwareTimeoutTransformer {
         this.readTimeoutMillis = readTimeout;
     }
 
-    protected byte[] doTransformClass(String className) throws Exception {
-        CtMethod connectMethod = findConnectMethod(className);
+    protected byte[] doTransformClass(CtClass cc) throws Exception {
+        CtMethod connectMethod = cc.getDeclaredMethod("connect");
         connectMethod.insertBefore("if ( getConnectTimeout() == 0 ) { setConnectTimeout(" + connectTimeoutMillis + "); }");
         connectMethod.insertBefore("if ( getReadTimeout() == 0 ) { setReadTimeout(" + readTimeoutMillis + "); }");
         byte[] classfileBuffer = connectMethod.getDeclaringClass().toBytecode();
         connectMethod.getDeclaringClass().detach();
         return classfileBuffer;
     }
-    
-    CtMethod findConnectMethod(String className) throws NotFoundException {
-        
-        ClassPool defaultPool = ClassPool.getDefault();
-        CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
-        if (cc == null) {
-            Log.get().log("No class found with name %s", className);
-            return null;
-        }
-        return cc.getDeclaredMethod("connect");
-
-    }
 
 }
\ No newline at end of file
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/MBeanAwareTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/MBeanAwareTimeoutTransformer.java
index 8211457..bf7eb02 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/MBeanAwareTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/MBeanAwareTimeoutTransformer.java
@@ -20,6 +20,10 @@ import java.lang.instrument.ClassFileTransformer;
 import java.security.ProtectionDomain;
 import java.util.Set;
 
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.bytecode.Descriptor;
+
 /**
  * Support class for transformers that expose runtime information through JMX
  * 
@@ -42,10 +46,15 @@ public abstract class MBeanAwareTimeoutTransformer implements ClassFileTransform
         try {
             if (classesToTransform.contains(className)) {
                 Log.get().log("%s asked to transform %s", getClass().getSimpleName(), className);
-                classfileBuffer = doTransformClass(className);
-                Log.get().log("Transformation complete.");
-                
-                this.agentInfo.registerTransformedClass(className);
+                ClassPool defaultPool = ClassPool.getDefault();
+                CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
+                if ( cc == null ) {
+                    Log.get().log("Could not find a class for %s in the default class pool, skipping transformation", className);
+                } else {
+                    classfileBuffer = doTransformClass(cc);
+                    Log.get().log("Transformation of %s complete", className);
+                    this.agentInfo.registerTransformedClass(className);
+                }
             }
             return classfileBuffer;
         } catch (Exception e) {
@@ -54,6 +63,13 @@ public abstract class MBeanAwareTimeoutTransformer implements ClassFileTransform
         }
     }
 
-    protected abstract byte[] doTransformClass(String className) throws Exception;
+    /**
+     * Transform a class that is guaranteed to exist and in scope of this agent instance
+     * 
+     * @param cc the class
+     * @return the new class definition
+     * @throws Exception in case of any problems while transforming
+     */
+    protected abstract byte[] doTransformClass(CtClass cc) throws Exception;
 
 }
\ No newline at end of file
diff --git a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
index 77ed113..3757137 100644
--- a/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
+++ b/url-connection-agent/src/main/java/org/apache/sling/uca/impl/UpdateFieldsInConstructorTimeoutTransformer.java
@@ -18,7 +18,6 @@ package org.apache.sling.uca.impl;
 
 import java.util.Collections;
 
-import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.CtConstructor;
 import javassist.CtField;
@@ -46,9 +45,7 @@ public abstract class UpdateFieldsInConstructorTimeoutTransformer extends MBeanA
     }
     
     @Override
-    protected byte[] doTransformClass(String className) throws Exception {
-        ClassPool defaultPool = ClassPool.getDefault();
-        CtClass cc = defaultPool.get(Descriptor.toJavaName(className));
+    protected byte[] doTransformClass(CtClass cc) throws Exception {
         
         CtConstructor noArgCtor = cc.getConstructor(Descriptor.ofConstructor(new CtClass[0]));
         CtField connectTimeout = cc.getDeclaredField(connectTimeoutFieldName);
diff --git a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/JaveNetTimeoutTransformerTest.java b/url-connection-agent/src/test/java/org/apache/sling/uca/impl/JaveNetTimeoutTransformerTest.java
deleted file mode 100644
index 9ddffde..0000000
--- a/url-connection-agent/src/test/java/org/apache/sling/uca/impl/JaveNetTimeoutTransformerTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.uca.impl;
-
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import javassist.NotFoundException;
-
-public class JaveNetTimeoutTransformerTest {
-    
-    private JavaNetTimeoutTransformer transformer;
-
-    @BeforeEach
-    public void initFields() {
-        transformer = new JavaNetTimeoutTransformer(1, 1, new AgentInfo(1, 1));
-    }
-
-    @Test
-    public void findDeclaredConnectMethod() throws NotFoundException {
-        assertNotNull(transformer.findConnectMethod("sun/net/www/protocol/http/HttpURLConnection"));
-    }
-
-    @Test
-    public void findInheritedConnectMethod() throws NotFoundException {
-        // do NOT look for inherited methods, as we can only rewrite the precise classes the
-        // retransform was triggered for
-        assertThrows( NotFoundException.class,
-            () -> transformer.findConnectMethod("sun/net/www/protocol/https/DelegateHttpsURLConnection")
-        );
-    }
-    
-}