/* * The JMockit Testing Toolkit * Copyright (c) 2006-2011 Rogério Liesenfeld * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.powermock.modules.agent; import java.io.IOException; import java.lang.instrument.Instrumentation; /** * This is the "agent class" that initializes the PowerMock "Java agent". It is not intended for use in client code. * It must be public, however, so the JVM can call the {@code premain} method, which as the name implies is called * <em>before</em> the {@code main} method. * * @see #premain(String, Instrumentation) */ public final class PowerMockAgent { static final String javaSpecVersion = System.getProperty("java.specification.version"); static final boolean jdk6OrLater = "1.6".equals(javaSpecVersion) || "1.7".equals(javaSpecVersion) || "1.8".equals(javaSpecVersion); private static final PowerMockClassTransformer classTransformer = new PowerMockClassTransformer(); private static Instrumentation instrumentation; private PowerMockAgent() {} public static boolean isJava6OrLater() { return jdk6OrLater; } /** * This method must only be called by the JVM, to provide the instrumentation object. * In order for this to occur, the JVM must be started with "-javaagent:powermock-module-javaagent-nnn.jar" as a command line parameter * (assuming the jar file is in the current directory). * */ public static void premain(String agentArgs, Instrumentation inst) throws Exception { initialize(agentArgs, inst); } @SuppressWarnings({"UnusedDeclaration"}) public static void agentmain(String agentArgs, Instrumentation inst) throws Exception { initialize(agentArgs, inst); } private static void initialize(String agentArgs, Instrumentation inst) throws IOException { instrumentation = inst; inst.addTransformer(new DefinalizingClassTransformer(), false); inst.addTransformer(classTransformer, true); } public static PowerMockClassTransformer getClasstransformer() { return classTransformer; } public static Instrumentation instrumentation() { verifyInitialization(); return instrumentation; } public static void verifyInitialization() { if (instrumentation == null) { new AgentInitialization().initializeAccordingToJDKVersion(); } } public static boolean initializeIfNeeded() { if (instrumentation == null) { try { new AgentInitialization().initializeAccordingToJDKVersion(); return true; } catch (RuntimeException e) { e.printStackTrace(); // makes sure the exception gets printed at least once throw e; } } return false; } public static void initializeIfPossible() { if (jdk6OrLater) { initializeIfNeeded(); } } }