001: /**************************************************************************************
002: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package org.codehaus.aspectwerkz.extension.jrockit;
008:
009: import org.codehaus.aspectwerkz.hook.ClassPreProcessor;
010: import org.codehaus.aspectwerkz.hook.impl.ClassPreProcessorHelper;
011: import com.bea.jvm.JVMFactory;
012: import com.jrockit.management.rmp.RmpSocketListener;
013:
014: /**
015: * JRockit (tested with 7SP4 and 8.1) preprocessor Adapter based on JMAPI <p/>JRockit has a low
016: * level API for hooking ClassPreProcessor, allowing the use of online weaving at full speed.
017: * Moreover, JRockit does not allow java.lang.ClassLoader overriding thru -Xbootclasspath/p option.
018: * <p/>The main difference with standard AspectWerkz online mode is that the ClassPreProcessor
019: * implementation and all third party jars CAN reside in the standard classpath. <p/>The command
020: * line tool will look like:
021: * <code>"%JAVA_COMMAND%" -Xmanagement:class=org.codehaus.aspectwerkz.extension.jrockit.JRockitPreProcessor
022: * -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%"
023: * -Daspectwerkz.home="%ASPECTWERKZ_HOME%" -Daspectwerkz.transform.verbose=yes %*</code>
024: * Note: there can be some NoClassDefFoundError due to classpath limitation - as described in
025: * http://edocs.bea.com/wls/docs81/adminguide/winservice.html <p/>In order to use the BEA JRockit
026: * management server (for further connection of management console or runtime analyzer), the regular
027: * option -Xmanagement will not have any effect. Instead, use <code>-Dmanagement</code>.
028: *
029: * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
030: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
031: */
032: public class JRockitPreProcessor implements
033: com.bea.jvm.ClassPreProcessor {
034:
035: /**
036: * Concrete AspectWerkz preprocessor.
037: */
038: private static ClassPreProcessor s_preProcessor;
039:
040: private static boolean START_RMP_SERVER = false;
041:
042: static {
043: String clpp = System
044: .getProperty("aspectwerkz.classloader.preprocessor",
045: "org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor");
046: START_RMP_SERVER = System.getProperties().containsKey(
047: "management");
048: try {
049: // note: CLPP loaded by current thread classloader which is bootstrap classloader
050: // caution: forcing loading thru Thread.setContextClassLoader() or
051: // ClassLoader.getSystemClassLoader()
052: // does not work. We then do a filtering on the caller classloader - see preProcess(..)
053: //preProcessor = (ClassPreProcessor) Class.forName(clpp).newInstance();
054: s_preProcessor = ClassPreProcessorHelper
055: .getClassPreProcessor();
056: //(ClassPreProcessor)ClassLoader.getSystemClassLoader().loadClass(clpp).newInstance();
057: //s_preProcessor.initialize(null);
058: } catch (Exception e) {
059: throw new ExceptionInInitializerError(
060: "could not initialize jrockit preprocessor due to: "
061: + e.toString());
062: }
063: }
064:
065: /**
066: * The JMAPI ClassPreProcessor must be self registrating
067: */
068: public JRockitPreProcessor() {
069: if (START_RMP_SERVER) {
070: // the management server will be spawned in a new thread
071: RmpSocketListener management = new RmpSocketListener();
072: }
073: JVMFactory.getJVM().getClassLibrary()
074: .setClassPreProcessor(this );
075: }
076:
077: /**
078: * Weave a class
079: *
080: * @param caller classloader
081: * @param name of the class to weave
082: * @param bytecode original
083: * @return bytecode weaved
084: */
085: public byte[] preProcess(ClassLoader caller, String name,
086: byte[] bytecode) {
087: if (caller == null || caller.getParent() == null) {
088: return bytecode;
089: } else {
090: return s_preProcessor.preProcess(name, bytecode, caller);
091: }
092: }
093:
094: /**
095: * Utility for testing
096: */
097: public static void main(String args[]) throws Throwable {
098: // uncomment this lines to programmaticaly configure at runtime the CLPP
099: JRockitPreProcessor pp = new JRockitPreProcessor();//self registration
100: Class loadedCP = Class.forName("java.math.BigDecimal");
101: while (true) {
102: System.out.print(".");
103: /*
104: * ClassLoader nonDelegatingCL = new VerifierClassLoader( new URL[]{(new
105: * File(args[0])).toURL()}, ClassLoader.getSystemClassLoader() ); Class loaded =
106: * nonDelegatingCL.loadClass(
107: * org.codehaus.aspectwerkz.extension.jrockit.JRockitPreProcessor.class.getName() );
108: */
109: Thread.sleep(500);
110: }
111: }
112: }
|