All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.newmainsoftech.aspectjutil.dynamicagent.DynamicAspectJWeaverAgent Maven / Gradle / Ivy

/*
 * Copyright (C) 2011-2013 NewMain Softech
 *
 * Licensed 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 com.newmainsoftech.aspectjutil.dynamicagent;

import java.io.File;
import java.io.FileFilter;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;

//note: including JavaDoc, intentionally avoid to make direct reference to classes in aspectjweaver.jar in this class.
/**
 * Wrapper class of AspectJ's Agent class, in order to support dynamic loading. 
* Though this class is not usually necessary in general because of existence of * WeavingURLClassLoader class in AspectJ, in some special case, this with * AspectJWeaverAgentLoader becomes useful for applying AspectJ's Agent * dynamically.
* * @see #agentmainWorker(String, Instrumentation) * @author Arata Y. */ public class DynamicAspectJWeaverAgent { //TODO create super class and extract general logic and methods to it. static Logger logger = Logger.getLogger( DynamicAspectJWeaverAgent.class.toString()); static Logger getLogger() { return logger; } public static final String AspectjWeaverAgentClassName = "org.aspectj.weaver.loadtime.Agent"; public static String getAspectjWeaverAgentClassName() { return AspectjWeaverAgentClassName; } private static Instrumentation instrumentation; static Instrumentation getInstrumentation() { return instrumentation; } synchronized static void setInstrumentation( final Instrumentation instrumentation) { DynamicAspectJWeaverAgent.instrumentation = instrumentation; } // Regarding name of options given to agentmain method ---------------------------------------- /** * For parsing argument given to {@link DynamicAspectJWeaverAgent#agentmain(String, Instrumentation)} * method and storing argument value. * * @author Arata Y. */ public static enum Option { /** * For argument of path to aspectjweaver.jar file that * {@link DynamicAspectJWeaverAgent#agentmain(String, Instrumentation)} method * adds it to application class path dynamically. * * * if agentmain method finds that * * * it cannot be loaded. */ AspectjWeaverJar( "aspectjweaverjar", String.class), /** * For argument going to given to premain method of agent class in .jar file specified by * the argument value of {@link Option#AspectjWeaverJar}. */ AspectjWeaverAgentMethodArg( "agent_method_arg", String.class), /** * For argument of paths to .jar files what will be added to application class path * (before enabling LTW) in {@link #agentmain(String, Instrumentation)} method. * For multiple paths, each path should have been separated by {@link File#pathSeparator}. */ AdditionalJarPaths( "jar_adition", (new String[]{}).getClass()), /** * For argument of switch whether checking jar file contains in the argument value of * {@link Option#AdditionalJarPaths} has been already loaded before adding to * application system class path. */ CheckJarAddition( "checkjaraddition", Boolean.class); private final String argName; public String getArgName() { return argName; } private final Class argValueType; public Class getArgValueType() { return argValueType; } private Option( final String argName, final Class argValueType) { this.argName = argName; this.argValueType = argValueType; } } private Map optionMap = new HashMap(); synchronized void setOptionValue( final Option option, final Object value) { if ( option == null) { throw new IllegalArgumentException( "value of option input cannot be null."); } if ( value != null) { if ( !value.getClass().equals( option.getArgValueType())) { throw new IllegalArgumentException( String.format( "value %1$s is not appropriate to be stored for %2$s " + "because its type (%3$s) is not expected type, %4$s.", value.toString(), option.name(), value.getClass().getName(), option.getArgValueType().getName() ) ); } } optionMap.put( option, value); } synchronized Object getOptionValue( final Option option) { if ( option == null) { throw new IllegalArgumentException( "value of option input cannot be null."); } Object argValue = optionMap.get( option); if ( option.getArgValueType().equals( (new String[]{}).getClass())) { if ( argValue != null) { return ((String[])argValue).clone(); } } else if ( Option.CheckJarAddition.equals( option)) { if ( argValue == null) { argValue = Boolean.TRUE; setOptionValue( option, argValue); } } return argValue; } // -------------------------------------------------------------------------------------------- protected void logginUnnecessityOfWeaverAgentLoad( Class aspectjAgentClass, String aspectjWeaverJarPath) { Logger logger = getLogger(); if ( logger.isLoggable( Level.WARNING)) { File aspectJWeaverAgentFile = null; try { aspectJWeaverAgentFile = new File( aspectjAgentClass.getProtectionDomain().getCodeSource() .getLocation().toURI()); } catch( Exception exception) { // Ignore } logger.log( Level.WARNING, String.format( "Proceeding without adding %1$s to application class " + "path since %2$s has already been loaded from %3$s. " + "If class loading problem occurs later as you may " + "expect because of having skipped adding it, then please " + "add it manually via Instrumentation instance " + "accessible by getInstrumentation method.", aspectjWeaverJarPath, aspectjAgentClass.getName(), ((aspectJWeaverAgentFile == null) ? "archival place" : aspectJWeaverAgentFile.getAbsolutePath()) ) ); } } /** * parse arguments given to {@link #agentmain(String, Instrumentation)} method. * When value of options input is null, do nothing. * @param options */ protected synchronized void parseOptions( final String options) { Logger logger = getLogger(); if ( logger.isLoggable( Level.FINER)) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[ 1]; logger.entering( stackTraceElement.getClassName(), stackTraceElement.getMethodName(), new Object[]{ options} ); } if ( options != null) { String optionsCopy = options.trim(); // Eliminate double-quotation characters at start and end of options input if ( options.matches( "^\"(.)*\"$")) { optionsCopy = optionsCopy.replaceAll( "^\"", "").replaceAll( "\"$", ""); } boolean agentMethodArgProcessingSign = false; // Switch to indicate if argument processing for Option.AspectjWeaverAgentMethodArg is // terminated or not. This boolean variable is for the case that argument to agent method // contains ',' character. boolean agentMethodArgIncident = false; // this is just to control logging for Option.AspectjWeaverAgentMethodArg for( String optionStr : optionsCopy.split( ",")) { String optionStrCopy = optionStr.trim(); // Eliminate double-quotation characters at start and end if ( optionStrCopy.matches( "^\"(.)*\"$")) { optionStrCopy = optionStrCopy.replaceAll( "^\"", "").replaceAll( "\"$", ""); } Option optionObj; if ( optionStrCopy.matches( "^" + Option.AspectjWeaverJar.getArgName() + " *=.+")) { agentMethodArgProcessingSign = false; optionObj = Option.AspectjWeaverJar; String[] optionTokenArray = optionStrCopy.split( "^" + optionObj.getArgName() + " *= *"); if ( optionTokenArray.length > 1) { setOptionValue( optionObj, optionTokenArray[ 1].replaceAll( "\"", "").trim()); if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Detected \"%1$s\" for %2$s argument.", getOptionValue( optionObj), optionObj.getArgName() )); } } } else if ( optionStrCopy.matches( "^" + Option.AspectjWeaverAgentMethodArg.getArgName() + " *=.+")) { agentMethodArgProcessingSign = true; agentMethodArgIncident = true; optionObj = Option.AspectjWeaverAgentMethodArg; String[] optionTokenArray = optionStrCopy.split( "^" + optionObj.getArgName() + " *= *"); if ( optionTokenArray.length > 1) { setOptionValue( optionObj, optionTokenArray[ 1].trim()); } // case of that ',' character is contained in argument to agent method will be // handled later else block. } else if ( optionStrCopy.matches( "^" + Option.AdditionalJarPaths.getArgName() + " *=.+")) { agentMethodArgProcessingSign = false; optionObj = Option.AdditionalJarPaths; String[] optionTokenArray = optionStrCopy.split( "^" + optionObj.getArgName() + " *= *"); if ( optionTokenArray.length > 1) { String[] jarPathArray = optionTokenArray[ 1].split( File.pathSeparator); for( int jarPathIndex = 0; jarPathIndex < jarPathArray.length; jarPathIndex++) { jarPathArray[ jarPathIndex] = jarPathArray[ jarPathIndex].replaceAll( "\"", "").trim(); } // for setOptionValue( optionObj, jarPathArray); if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Detected \"%1$s\" for %2$s argument.", Arrays.toString( jarPathArray), optionObj.getArgName() )); } } } else if ( optionStrCopy.matches( "^" + Option.CheckJarAddition.getArgName() + " *=.+")) { agentMethodArgProcessingSign = false; optionObj = Option.CheckJarAddition; String[] optionTokenArray = optionStrCopy.split( "^" + optionObj.getArgName() + " *= *"); boolean argValue = true; if ( optionTokenArray.length > 1) { if ( optionTokenArray[ 1] != null) { if ( optionTokenArray[ 1].trim().toLowerCase() .matches( "^\"?((false)|(no)|(off))\"?$")) { argValue = false; } } } setOptionValue( optionObj, Boolean.valueOf( argValue)); if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Detected \"%1$b\" for %2$s argument.", argValue, optionObj.getArgName() )); } } else { // the case that argument to agent method contains ',' character. if ( agentMethodArgProcessingSign) { optionObj = Option.AspectjWeaverAgentMethodArg; String argStockForAgentMethodArg = (String)(getOptionValue( optionObj)); if ( argStockForAgentMethodArg == null) { argStockForAgentMethodArg = ""; } if ( argStockForAgentMethodArg.length() < 1) { setOptionValue( optionObj, optionStr.trim()); } else { setOptionValue( optionObj, argStockForAgentMethodArg + "," + optionStr.trim()); } } } } // for if ( agentMethodArgIncident) { if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Detected \"%1$s\" for %2$s argument.", getOptionValue( Option.AspectjWeaverAgentMethodArg), Option.AspectjWeaverAgentMethodArg.getArgName() )); } } } if ( logger.isLoggable( Level.FINER)) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[ 1]; logger.exiting( stackTraceElement.getClassName(), stackTraceElement.getMethodName() ); } } public static enum AgentType { Agentmain( "Agent-Class", "agentmain"), Premain( "Premain-Class", "premain"); private final String manifestAttributeName; public String getManifestAttributeName() { return manifestAttributeName; } private final String agentMethodName; public String getAgentMethodName() { return agentMethodName; } private AgentType( String manifestAttributeName, String agentMethodName) { this.manifestAttributeName = manifestAttributeName; this.agentMethodName = agentMethodName; } } static class AgentInfo { private JarFile agentJarFile; JarFile getAgentJarFile() { return agentJarFile; } void setAgentJarFile( final JarFile agentJarFile) { this.agentJarFile = agentJarFile; } private AgentType agentType; AgentType getAgentType() { return agentType; } void setAgentType( final AgentType agentType) { this.agentType = agentType; } private String agentClassName; String getAgentClassName() { return agentClassName; } void setAgentClassName( final String agentClassName) { this.agentClassName = agentClassName; } private Class agentClass; Class getAgentClass() { return agentClass; } void setAgentClass( final Class agentClass) { this.agentClass = agentClass; } } /** * Extract class name having set for either Agent-Class or Premain-Class attribute in * MANIFEST.MF of given jarFile input.
* Agent-Class attribute has precedence over Premain-Class attribute when both attribute entries * are found.
* If neither of attributes is found, then null will be returned. * @param jarFile * @return AgentInfo object having set member fiels except {@link AgentInfo#agentClass}, or null. */ AgentInfo extractAgentInfo( final JarFile jarFile) { if ( jarFile == null) { throw new IllegalArgumentException( "Value of jarFile cannot be null."); } AgentInfo agentInfo = new AgentInfo(); agentInfo.setAgentJarFile( jarFile); try { for( AgentType agentType = AgentType.Agentmain; agentInfo.getAgentClassName() == null; agentType = AgentType.Premain ) { agentInfo.setAgentType( agentType); agentInfo.setAgentClassName( jarFile.getManifest() .getMainAttributes().getValue( agentType.getManifestAttributeName()) ); if ( agentType.equals( AgentType.Premain)) { break; // for } } // for } catch( Exception exception) { throw new IllegalArgumentException( String.format( "Failure in accessing MANIFEST.MF in %1$s (given by %2$s argument)", jarFile.getName(), Option.AspectjWeaverJar.getArgName() ), exception); } if ( agentInfo.getAgentClassName() == null) agentInfo = null; return agentInfo; } File locateAspectJWeaverJar() { // Try to get path to aspectjweaver.jar from system property File aspectJWeaverArchive = null; String aspectjHomePath = System.getenv( "ASPECTJ_HOME"); if ( aspectjHomePath != null) { File aspectjHomeDir = new File( aspectjHomePath); if ( aspectjHomeDir.exists() && aspectjHomeDir.isDirectory()) { if( "bin".equals( aspectjHomeDir.getName())) { aspectjHomeDir = aspectjHomeDir.getParentFile(); } File aspectjLibDir = new File( aspectjHomeDir, "lib"); if ( aspectjHomeDir.exists() && aspectjHomeDir.isDirectory()) { FileFilter fileFilter = new FileFilter() { @Override public boolean accept( File file) { if ( !file.isFile()) return false; //ex. aspectjweaver-1.7.0.jar String fileName = file.getName().toLowerCase(); if ( !fileName.endsWith( ".jar")) return false; if ( fileName.startsWith( "aspectjweaver")) return true; return false; } }; File[] fileArray = aspectjLibDir.listFiles( fileFilter); if ( fileArray.length == 1) { aspectJWeaverArchive = fileArray[ 0]; } else { Logger logger = getLogger(); if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Could not determine AspectJ Weaver .jar file in " + "%1$s directory: %2$s", aspectjLibDir.getAbsolutePath(), (( fileArray.length == 0) ? "no candidate" : Arrays.toString( fileArray)) ) ); } } } } } if ( aspectJWeaverArchive == null) { throw new UnsupportedOperationException( String.format( "Could not load %1$s class. To enable AspectJ's load time " + "weaving, either start application with pointing " + "aspectjweaver.jar with -javaagent JVM parameter, use " + "custom class loader (such as WeavingURLClassLoader), or use " + "AspectJWeaverAgentLoader and %2$s with giving either path to " + "aspectjweaver.jar or setting ASPECTJ_HOME system environment " + "variable pointing AspectJ installation directory.", DynamicAspectJWeaverAgent.getAspectjWeaverAgentClassName(), DynamicAspectJWeaverAgent.class.getSimpleName() ) ); } return aspectJWeaverArchive; } /** * Actual worker method called by {@link #agentmain(String, Instrumentation)} method.
* This is to enable AspectJ's LTW (load time weaving) dynamically.
* In this method, the execution process progresses like: *
    *
  1. Add AspectJ's agent .jar file specified by argument in options input to * application's system class path, if it has not been loaded. The name of argument in * options input is identified by AspectjWeaverJar.getArgName method of * {@link Option} enum.
  2. *
  3. If AspectJ's agent .jar file is not given by the argument, add aspectjweaver.jar * at where ASPECTJ_HOME system environment variable points to application's system class path.
  4. *
  5. Add additional .jar files given by the argument (of what name is identified * by AdditionalJarPaths.getArgName method of {@link Option} enum) in options * input to application's system class path.
  6. *
  7. Call agentmain method of the subject agent if it can be found.
    * If not, then call premain method instead.
  8. *
* * @param options may specify the path to agent's .jar, paths of additional jar files, and * arguments to either agentmain or premain method of the subject's agent.
* For name of arguments, see {@link Option}. * @param instrumentation should be given automatically by Attach API component. */ protected synchronized void agentmainWorker( final String options, final Instrumentation instrumentation) { Logger logger = getLogger(); if ( logger.isLoggable( Level.FINER)) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[ 1]; logger.entering( stackTraceElement.getClassName(), stackTraceElement.getMethodName(), new Object[]{ options, instrumentation} ); } if ( instrumentation == null) { throw new IllegalArgumentException( "Value of instrumentation input cannot be null."); } DynamicAspectJWeaverAgent.setInstrumentation( instrumentation); // parsing options parseOptions( options); // Add agent jar to application class path if it has not been loaded yet ------------------ AgentInfo agentInfo = null; if ( getOptionValue( Option.AspectjWeaverJar) != null) { String aspectjWeaverJarPath = (String)(getOptionValue( Option.AspectjWeaverJar)); File aspectjWeaverFile = new File( aspectjWeaverJarPath); JarFile aspectjWeaverJarFile = null; try { aspectjWeaverJarFile = new JarFile( aspectjWeaverFile); } catch( Exception exception) { throw new IllegalArgumentException( String.format( "Failure in handling %1$s (given by %2$s argument) as an .jar file.", aspectjWeaverJarPath, Option.AspectjWeaverJar.getArgName() ), exception); } agentInfo = extractAgentInfo( aspectjWeaverJarFile); if ((agentInfo != null) && (agentInfo.getAgentClassName() != null)) { // Check whether Agent has been already loaded by system class loader AgentAssistant agentAssistant = new AgentAssistant(); agentInfo.setAgentClass( agentAssistant.hasLoaded( agentInfo.getAgentClassName(), instrumentation)); if ( agentInfo.getAgentClass() != null) { logginUnnecessityOfWeaverAgentLoad( agentInfo.getAgentClass(), aspectjWeaverJarPath); } else { // Check whether Agent has been already in application class path ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); try { agentInfo.setAgentClass( systemClassLoader.loadClass( agentInfo.getAgentClassName())); } catch( ClassNotFoundException exception) { // ignore } if ( agentInfo.getAgentClass() != null) { logginUnnecessityOfWeaverAgentLoad( agentInfo.getAgentClass(), aspectjWeaverJarPath); } else { // add agent jar to application's system class path instrumentation.appendToSystemClassLoaderSearch( aspectjWeaverJarFile); if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Succeeded to add %1$s to class path of application.", aspectjWeaverJarPath ) ); } try { agentInfo.setAgentClass( systemClassLoader.loadClass( agentInfo.getAgentClassName())); } catch ( Exception exception) { throw new RuntimeException( String.format( "Failure in loading %1$s by system class loader after " + "adding %2$s to application's system class path.", agentInfo.getAgentClassName(), aspectjWeaverJarPath ), exception); } } } } else { throw new IllegalArgumentException( String.format( "Cannot find Agent-Class or Premain-Class entry in main attribute " + "seciton of MANIFEST.MF file in %1$s", aspectjWeaverJarPath) ); } } else { // Check whether aspectjweaver agent has been loaded boolean hasAspectjWeaverLoaded = false; agentInfo = new AgentInfo(); agentInfo.setAgentClassName( DynamicAspectJWeaverAgent.getAspectjWeaverAgentClassName()); AgentAssistant agentAssistant = new AgentAssistant(); agentInfo.setAgentClass( agentAssistant.hasLoaded( agentInfo.getAgentClassName(), instrumentation)); if ( agentInfo.getAgentClass() != null) { hasAspectjWeaverLoaded = true; } else { // Check whether Agent has been already in application class path ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); try { agentInfo.setAgentClass( systemClassLoader.loadClass( agentInfo.getAgentClassName())); } catch( ClassNotFoundException exception) { // Ignore } if ( agentInfo.getAgentClass() != null) { hasAspectjWeaverLoaded = true; } } // If not, then try to load from where ASPECTJ_HOME system environment variable points if ( !hasAspectjWeaverLoaded) { File aspectJWeaverArchiveFile = locateAspectJWeaverJar(); // add aspectjweaver.jar to application's system class path JarFile aspectjWeaverJarFile = null; try { aspectjWeaverJarFile = new JarFile( aspectJWeaverArchiveFile); instrumentation.appendToSystemClassLoaderSearch( aspectjWeaverJarFile); if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Succeeded to add %1$s to class path of application.", aspectJWeaverArchiveFile ) ); } } catch( Exception exception) { if ( exception instanceof RuntimeException) throw (RuntimeException)exception; throw new RuntimeException( String.format( "Failed adding %1$s to class path of application " + "in enabling AspectJ's load time weaving.", aspectJWeaverArchiveFile ), exception); } agentInfo = extractAgentInfo( aspectjWeaverJarFile); if ((agentInfo != null) && (agentInfo.getAgentClassName() != null)) { ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); try { agentInfo.setAgentClass( systemClassLoader.loadClass( agentInfo.getAgentClassName())); } catch ( Exception exception) { throw new RuntimeException( String.format( "Failure in loading %1$s by system class loader after " + "adding %2$s to application's system class path.", agentInfo.getAgentClassName(), aspectJWeaverArchiveFile ), exception); } } else { throw new IllegalArgumentException( String.format( "Cannot find Agent-Class or Premain-Class entry in main attribute " + "seciton of MANIFEST.MF file in %1$s", aspectjWeaverJarFile.getName()) ); } } } // ---------------------------------------------------------------------------------------- // Add additional jars to application class path ------------------------------------------ if ( getOptionValue( Option.AdditionalJarPaths) != null) { boolean checkJarAddition = true; if ( getOptionValue( Option.CheckJarAddition) != null) { checkJarAddition = ((Boolean)(getOptionValue( Option.CheckJarAddition))).booleanValue(); } AgentAssistant agentAssistant = new AgentAssistant(); agentAssistant.addAdditionalJarPathsToSystemClassPath( (String[])(getOptionValue( Option.AdditionalJarPaths)), checkJarAddition, instrumentation ); } // ---------------------------------------------------------------------------------------- Instrumentation superInstrumentationObj = null; try { Method getInstrumentationMethod = agentInfo.getAgentClass().getMethod( "getInstrumentation", (Class[])null); getInstrumentationMethod.setAccessible( true); superInstrumentationObj = (Instrumentation)getInstrumentationMethod.invoke( null, (Object[])null); } catch( Exception exception) { // Do nothing } if ( superInstrumentationObj != null) { if ( logger.isLoggable( Level.INFO)) { logger.log( Level.INFO, String.format( "%1$s JavaAgent has already been enabled.", agentInfo.getAgentClass().getSimpleName() ) ); } } else { Method agentMethod = null; try { agentMethod = agentInfo.getAgentClass().getMethod( agentInfo.getAgentType().getAgentMethodName(), String.class, Instrumentation.class); } catch( Exception exception) { throw new RuntimeException( String.format( "Could not find %1$s static method in %2$s.", agentInfo.getAgentType().getAgentMethodName(), agentInfo.getAgentClass().getName() ), exception ); } agentMethod.setAccessible( true); try { agentMethod.invoke( null, getOptionValue( Option.AspectjWeaverAgentMethodArg), instrumentation); if ( logger.isLoggable( Level.FINE)) { logger.log( Level.FINE, String.format( "Succeded to call %1$s static method of %2$s JavaAgent to " + "dynamically enable it.", agentMethod.getName(), agentInfo.getAgentClass().getSimpleName() ) ); } } catch( Exception exception) { if ( exception instanceof RuntimeException) throw (RuntimeException)exception; String agentArchivePath = ""; try { File agentArchiveFile = new File( agentInfo.getAgentClass().getProtectionDomain().getCodeSource() .getLocation().toURI()); agentArchivePath = String.format( "from %1$s ", agentArchiveFile.getAbsolutePath() ); } catch( Exception ignored) { // ignore } throw new RuntimeException( String.format( "Failure in invoking %1$s static method of %2$s class %3$s" + "in order to dynamically enable it.", agentMethod.getName(), agentInfo.getAgentClass().getName(), agentArchivePath ), exception ); } } if ( logger.isLoggable( Level.FINER)) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[ 1]; logger.exiting( stackTraceElement.getClassName(), stackTraceElement.getMethodName() ); } } /** * Java agent method wrapping {@link #agentmainWorker(String, Instrumentation)} method. * * @param options will be handed over to agentmainWorker method. * @param instrumentation will be handed over to agentmainWorker method. * @see #agentmainWorker(String, Instrumentation) */ public synchronized static void agentmain( final String options, final Instrumentation instrumentation) { (new DynamicAspectJWeaverAgent()).agentmainWorker( options, instrumentation); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy