diff options
author | mwebster <mwebster> | 2006-06-09 10:56:50 +0000 |
---|---|---|
committer | mwebster <mwebster> | 2006-06-09 10:56:50 +0000 |
commit | 75afb31e38f75e61de5c15058d3332f3dac0df15 (patch) | |
tree | bf0be856748d641f3dfcc0d49f80524c8d65b6a3 /loadtime/src | |
parent | 4db50ddb1edbae0baa447a22eb18b1c60e26d5a5 (diff) | |
download | aspectj-75afb31e38f75e61de5c15058d3332f3dac0df15.tar.gz aspectj-75afb31e38f75e61de5c15058d3332f3dac0df15.zip |
Fix for 122580 "Circularity Failure for Verbose Loading on JRockit 1.4.2_08 Agent"
1. New JRockitAgent
2. New lib/ext/jrocket/jrockit.jar for dependencies
3. New JRockitAgent tests
Diffstat (limited to 'loadtime/src')
-rw-r--r-- | loadtime/src/org/aspectj/weaver/loadtime/Aj.java | 2 | ||||
-rw-r--r-- | loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java | 129 |
2 files changed, 69 insertions, 62 deletions
diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java index fd045c3e6..5c8336135 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java @@ -63,7 +63,7 @@ public class Aj implements ClassPreProcessor { return bytes; } return weavingAdaptor.weaveClass(className, bytes); - } catch (Throwable t) { + } catch (Exception t) { //FIXME AV wondering if we should have the option to fail (throw runtime exception) here // would make sense at least in test f.e. see TestHelper.handleMessage() t.printStackTrace(); diff --git a/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java b/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java index 3d29089bd..667b74e04 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/JRockitAgent.java @@ -1,77 +1,84 @@ /******************************************************************************* - * Copyright (c) 2005 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://eclipse.org/legal/epl-v10.html + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Alexandre Vasseur initial implementation (derivative from AspectWerkz) + * Matthew Webster - initial implementation *******************************************************************************/ package org.aspectj.weaver.loadtime; +import java.util.Stack; + +import com.bea.jvm.ClassLibrary; import com.bea.jvm.JVMFactory; -import com.jrockit.management.rmp.RmpSocketListener; /** - * JRockit (tested with 7SP4 and 8.1) preprocessor Adapter based on JMAPI <p/>JRockit has a low - * level API for hooking ClassPreProcessor, allowing the use of online weaving at full speed. - * Moreover, JRockit does not allow java.lang.ClassLoader overriding thru -Xbootclasspath/p option. - * <p/>The ClassPreProcessor - * implementation and all third party jars CAN reside in the standard classpath. <p/>The command - * line will look like: - * <code>"%JAVA_COMMAND%" -Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent -cp ...</code> - * Note: there can be some NoClassDefFoundError due to classpath limitation - as described in - * http://edocs.bea.com/wls/docs81/adminguide/winservice.html <p/>In order to use the BEA JRockit - * management server (for further connection of management console or runtime analyzer), the regular - * option -Xmanagement will not have any effect prior to JRockit 8.1 SP2. Instead, use <code>-Dmanagement</code>. - * - * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + * BEA JRocket JMAPI agent. + * + * Use "-Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent" */ public class JRockitAgent implements com.bea.jvm.ClassPreProcessor { - /** - * Concrete preprocessor - */ - private final static ClassPreProcessor s_preProcessor; + private ClassPreProcessor preProcessor; + + /* + * This is used to implement the recursion protection offered by JVMTI + * but not by JRockit JMAPI. I we are called to preProcess a class while + * already preProcessing another we will return immediately + */ + private static ThreadLocalStack stack = new ThreadLocalStack(); + + + public JRockitAgent () { + this.preProcessor = new Aj(); + + ClassLibrary cl = JVMFactory.getJVM().getClassLibrary(); + cl.setClassPreProcessor(this); + } + + public byte[] preProcess(ClassLoader loader, String className, byte[] bytes) { + byte[] newBytes = bytes; + + if (stack.empty()) { + stack.push(className); + newBytes = preProcessor.preProcess(className, bytes, loader); + stack.pop(); + } + + return newBytes; + } - private static boolean START_RMP_SERVER = false; + private static class ThreadLocalStack extends ThreadLocal { - static { - START_RMP_SERVER = System.getProperties().containsKey("management"); - try { - s_preProcessor = new Aj(); - s_preProcessor.initialize(); - } catch (Exception e) { - throw new ExceptionInInitializerError("could not initialize JRockitAgent preprocessor due to: " + e.toString()); - } - } + public boolean empty () { + Stack stack = (Stack)get(); + return stack.empty(); + } - /** - * The JMAPI ClassPreProcessor must be self registrating - */ - public JRockitAgent() { - if (START_RMP_SERVER) { - // the management server will be spawned in a new thread - /*RmpSocketListener management = */new RmpSocketListener(); - } - JVMFactory.getJVM().getClassLibrary().setClassPreProcessor(this); - } + public Object peek () { + Object obj = null; + Stack stack = (Stack)get(); + if (!stack.empty()) obj = stack.peek(); + return obj; + } + + public void push (Object obj) { + Stack stack = (Stack)get(); + if (!stack.empty() && obj == stack.peek()) throw new RuntimeException(obj.toString()); + stack.push(obj); + } + + public Object pop () { + Stack stack = (Stack)get(); + return stack.pop(); + } + + protected Object initialValue() { + return new Stack(); + } + } - /** - * Weave a class - * - * @param caller classloader - * @param name of the class to weave - * @param bytecode original - * @return bytecode weaved - */ - public byte[] preProcess(ClassLoader caller, String name, byte[] bytecode) { - if (caller == null || caller.getParent() == null) { - return bytecode; - } else { - return s_preProcessor.preProcess(name, bytecode, caller); - } - } -}
\ No newline at end of file +} |