/************************************************************************************** * Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved. * * http://aspectwerkz.codehaus.org * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the LGPL license * * a copy of which has been included with this distribution in the license.txt file. * **************************************************************************************/ package org.codehaus.aspectwerkz.extension.jrockit; import org.codehaus.aspectwerkz.hook.ClassPreProcessor; import org.codehaus.aspectwerkz.hook.impl.ClassPreProcessorHelper; 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 main difference with standard AspectWerkz online mode is that the ClassPreProcessor * implementation and all third party jars CAN reside in the standard classpath. <p/>The command * line tool will look like: * <code>"%JAVA_COMMAND%" -Xmanagement:class=org.codehaus.aspectwerkz.extension.jrockit.JRockitPreProcessor * -cp "%ASPECTWERKZ_HOME%\target\aspectwerkz-extensions-%ASPECTWERKZ_VERSION%.jar;%ASPECTWERKZ_HOME%\lib\aspectwerkz-core-%ASPECTWERKZ_VERSION%.jar;%ASPECTWERKZ_HOME%\lib\aspectwerkz-%ASPECTWERKZ_VERSION%.jar;%ASPECTWERKZ_LIBS%" * -Daspectwerkz.transform.verbose=yes %*</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. Instead, use <code>-Dmanagement</code>. * * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a> * @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r </a> */ public class JRockitPreProcessor implements com.bea.jvm.ClassPreProcessor { /** * Concrete AspectWerkz preprocessor. */ private static ClassPreProcessor s_preProcessor; private static boolean START_RMP_SERVER = false; static { String clpp = System.getProperty( "aspectwerkz.classloader.preprocessor", "org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor" ); START_RMP_SERVER = System.getProperties().containsKey("management"); try { // note: CLPP loaded by current thread classloader which is bootstrap classloader // caution: forcing loading thru Thread.setContextClassLoader() or // ClassLoader.getSystemClassLoader() // does not work. We then do a filtering on the caller classloader - see preProcess(..) //preProcessor = (ClassPreProcessor) Class.forName(clpp).newInstance(); s_preProcessor = ClassPreProcessorHelper.getClassPreProcessor(); //(ClassPreProcessor)ClassLoader.getSystemClassLoader().loadClass(clpp).newInstance(); //s_preProcessor.initialize(null); } catch (Exception e) { throw new ExceptionInInitializerError("could not initialize jrockit preprocessor due to: " + e.toString()); } } /** * The JMAPI ClassPreProcessor must be self registrating */ public JRockitPreProcessor() { if (START_RMP_SERVER) { // the management server will be spawned in a new thread RmpSocketListener management = new RmpSocketListener(); } JVMFactory.getJVM().getClassLibrary().setClassPreProcessor(this); } /** * 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); } } /** * Utility for testing */ public static void main(String args[]) throws Throwable { // uncomment this lines to programmaticaly configure at runtime the CLPP JRockitPreProcessor pp = new JRockitPreProcessor();//self registration Class loadedCP = Class.forName("java.math.BigDecimal"); while (true) { System.out.print("."); /* * ClassLoader nonDelegatingCL = new VerifierClassLoader( new URL[]{(new * File(args[0])).toURL()}, ClassLoader.getSystemClassLoader() ); Class loaded = * nonDelegatingCL.loadClass( * org.codehaus.aspectwerkz.extension.jrockit.JRockitPreProcessor.class.getName() ); */ Thread.sleep(500); } } }