From 75afb31e38f75e61de5c15058d3332f3dac0df15 Mon Sep 17 00:00:00 2001 From: mwebster Date: Fri, 9 Jun 2006 10:56:50 +0000 Subject: 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 --- loadtime/src/org/aspectj/weaver/loadtime/Aj.java | 2 +- .../org/aspectj/weaver/loadtime/JRockitAgent.java | 129 +++++++++++---------- 2 files changed, 69 insertions(+), 62 deletions(-) (limited to 'loadtime/src') 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

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. - *

The ClassPreProcessor - * implementation and all third party jars CAN reside in the standard classpath.

The command - * line will look like: - * "%JAVA_COMMAND%" -Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent -cp ... - * Note: there can be some NoClassDefFoundError due to classpath limitation - as described in - * http://edocs.bea.com/wls/docs81/adminguide/winservice.html

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 -Dmanagement. - * - * @author Alexandre Vasseur + * 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 +} -- cgit v1.2.3