首先看jacoco premain 入口:

/******************************************************************************** Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and 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://www.eclipse.org/legal/epl-v10.html** Contributors:*    Marc R. Hoffmann - initial API and implementation*    *******************************************************************************/
package org.jacoco.agent.rt.internal;import java.lang.instrument.Instrumentation;import org.jacoco.core.runtime.AgentOptions;
import org.jacoco.core.runtime.IRuntime;
import org.jacoco.core.runtime.ModifiedSystemClassRuntime;/*** The agent which is referred as the <code>Premain-Class</code>. The agent* configuration is provided with the agent parameters in the command line.*/
public final class PreMain {private PreMain() {// no instances}/*** This method is called by the JVM to initialize Java agents.* * @param options*            agent options* @param inst*            instrumentation callback provided by the JVM* @throws Exception*             in case initialization fails*/public static void premain(final String options, final Instrumentation inst)throws Exception {final AgentOptions agentOptions = new AgentOptions(options);final Agent agent = Agent.getInstance(agentOptions);final IRuntime runtime = createRuntime(inst);runtime.startup(agent.getData());inst.addTransformer(new CoverageTransformer(runtime, agentOptions,IExceptionLogger.SYSTEM_ERR));}private static IRuntime createRuntime(final Instrumentation inst)throws Exception {return ModifiedSystemClassRuntime.createFor(inst, "java/lang/UnknownError");}}

入口函数premain:  参数 Instrumentation类是java.lang 下面的类

public static void premain(final String options, final Instrumentation inst)throws Exception {final AgentOptions agentOptions = new AgentOptions(options);final Agent agent = Agent.getInstance(agentOptions);final IRuntime runtime = createRuntime(inst);runtime.startup(agent.getData());inst.addTransformer(new CoverageTransformer(runtime, agentOptions,IExceptionLogger.SYSTEM_ERR));}

然后调用了CoverageTransformer 类,这个类和 premain同一个包下面:

看下 CoverageTransformer 类:

/******************************************************************************** Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and 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://www.eclipse.org/legal/epl-v10.html** Contributors:*    Marc R. Hoffmann - initial API and implementation*    *******************************************************************************/
package org.jacoco.agent.rt.internal;import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.CodeSource;
import java.security.ProtectionDomain;import org.jacoco.core.instr.Instrumenter;
import org.jacoco.core.runtime.AgentOptions;
import org.jacoco.core.runtime.IRuntime;
import org.jacoco.core.runtime.WildcardMatcher;/*** Class file transformer to instrument classes for code coverage analysis.*/
public class CoverageTransformer implements ClassFileTransformer {private static final String AGENT_PREFIX;static {final String name = CoverageTransformer.class.getName();AGENT_PREFIX = toVMName(name.substring(0, name.lastIndexOf('.')));}private final Instrumenter instrumenter;private final IExceptionLogger logger;private final WildcardMatcher includes;private final WildcardMatcher excludes;private final WildcardMatcher exclClassloader;private final ClassFileDumper classFileDumper;private final boolean inclBootstrapClasses;private final boolean inclNoLocationClasses;/*** New transformer with the given delegates.* * @param runtime*            coverage runtime* @param options*            configuration options for the generator* @param logger*            logger for exceptions during instrumentation*/public CoverageTransformer(final IRuntime runtime,final AgentOptions options, final IExceptionLogger logger) {this.instrumenter = new Instrumenter(runtime);this.logger = logger;// Class names will be reported in VM notation:includes = new WildcardMatcher(toVMName(options.getIncludes()));excludes = new WildcardMatcher(toVMName(options.getExcludes()));exclClassloader = new WildcardMatcher(options.getExclClassloader());classFileDumper = new ClassFileDumper(options.getClassDumpDir());inclBootstrapClasses = options.getInclBootstrapClasses();inclNoLocationClasses = options.getInclNoLocationClasses();}public byte[] transform(final ClassLoader loader, final String classname,final Class<?> classBeingRedefined,final ProtectionDomain protectionDomain,final byte[] classfileBuffer) throws IllegalClassFormatException {// We do not support class retransformation:if (classBeingRedefined != null) {return null;}if (!filter(loader, classname, protectionDomain)) {return null;}try {classFileDumper.dump(classname, classfileBuffer);return instrumenter.instrument(classfileBuffer, classname);} catch (final Exception ex) {final IllegalClassFormatException wrapper = new IllegalClassFormatException(ex.getMessage());wrapper.initCause(ex);// Report this, as the exception is ignored by the JVM:logger.logExeption(wrapper);throw wrapper;}}/*** Checks whether this class should be instrumented.* * @param loader*            loader for the class* @param classname*            VM name of the class to check* @param protectionDomain*            protection domain for the class* @return <code>true</code> if the class should be instrumented*/boolean filter(final ClassLoader loader, final String classname,final ProtectionDomain protectionDomain) {if (loader == null) {if (!inclBootstrapClasses) {return false;}} else {if (!inclNoLocationClasses && !hasSourceLocation(protectionDomain)) {return false;}if (exclClassloader.matches(loader.getClass().getName())) {return false;}}return !classname.startsWith(AGENT_PREFIX) &&includes.matches(classname) &&!excludes.matches(classname);}/*** Checks whether this protection domain is associated with a source* location.* * @param protectionDomain*            protection domain to check (or <code>null</code>)* @return <code>true</code> if a source location is defined*/private boolean hasSourceLocation(final ProtectionDomain protectionDomain) {if (protectionDomain == null) {return false;}final CodeSource codeSource = protectionDomain.getCodeSource();if (codeSource == null) {return false;}return codeSource.getLocation() != null;}private static String toVMName(final String srcName) {return srcName.replace('.', '/');}}

这个类中关键方法:

public byte[] transform(final ClassLoader loader, final String classname,final Class<?> classBeingRedefined,final ProtectionDomain protectionDomain,final byte[] classfileBuffer) throws IllegalClassFormatException {// We do not support class retransformation:if (classBeingRedefined != null) {return null;}if (!filter(loader, classname, protectionDomain)) {return null;}try {classFileDumper.dump(classname, classfileBuffer);return instrumenter.instrument(classfileBuffer, classname);} catch (final Exception ex) {final IllegalClassFormatException wrapper = new IllegalClassFormatException(ex.getMessage());wrapper.initCause(ex);// Report this, as the exception is ignored by the JVM:logger.logExeption(wrapper);throw wrapper;}}

调用了classFileDumper 类:

/******************************************************************************** Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and 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://www.eclipse.org/legal/epl-v10.html** Contributors:*    Marc R. Hoffmann - initial API and implementation*    *******************************************************************************/
package org.jacoco.agent.rt.internal;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;import org.jacoco.core.internal.data.CRC64;/*** Internal dumper for class files.*/
class ClassFileDumper {private final File location;/*** Create a new dumper for the given location.* * @param location*            relative path to dump directory. <code>null</code> if no dumps*            should be written*/ClassFileDumper(final String location) {if (location == null) {this.location = null;} else {this.location = new File(location);}}/*** Dumps the given binary content under the given name if a non-* <code>null</code> location has been specified.* * @param name*            qualified class name in VM notation* @param contents*            binary contents* @throws IOException*             in case of problems while dumping the file*/void dump(final String name, final byte[] contents) throws IOException {if (location != null) {final File outputdir;final String localname;final int pkgpos = name.lastIndexOf('/');if (pkgpos != -1) {outputdir = new File(location, name.substring(0, pkgpos));localname = name.substring(pkgpos + 1);} else {outputdir = location;localname = name;}outputdir.mkdirs();final Long id = Long.valueOf(CRC64.classId(contents));final File file = new File(outputdir, String.format("%s.%016x.class", localname, id));final OutputStream out = new FileOutputStream(file);out.write(contents);out.close();}}}

这个类将class out 输出,上面transform方法在调用的时候同时使用:

classFileDumper.dump(classname, classfileBuffer);
return instrumenter.instrument(classfileBuffer, classname);

final class InstrSupport类:

public static final String DATAFIELD_DESC = "[Z";// === Init Method ===/*** Name of the initialization method.*/public static final String INITMETHOD_NAME = "$jacocoInit";/*** Descriptor of the initialization method.*/public static final String INITMETHOD_DESC = "()[Z";public static void assertNotInstrumented(final String member,final String owner) throws IllegalStateException {if (member.equals(DATAFIELD_NAME) || member.equals(INITMETHOD_NAME)) {throw new IllegalStateException(format("Class %s is already instrumented.", owner));}}

这个类是final 主要作为单例的使用,ClassInstrumenter, ClassAnalyzer调用InstrSupport

ClassAnalyzer 类调用如下:

@Overridepublic MethodProbesVisitor visitMethod(final int access, final String name,final String desc, final String signature, final String[] exceptions) {InstrSupport.assertNotInstrumented(name, coverage.getName());return new MethodAnalyzer(coverage.getName(), coverage.getSuperName(),stringPool.get(name), stringPool.get(desc),stringPool.get(signature), probes, Filters.ALL) {@Overridepublic void visitEnd() {super.visitEnd();final IMethodCoverage methodCoverage = getCoverage();if (methodCoverage.getInstructionCounter().getTotalCount() > 0) {// Only consider methods that actually contain codecoverage.addMethod(methodCoverage);}}};}@Overridepublic FieldVisitor visitField(final int access, final String name,final String desc, final String signature, final Object value) {InstrSupport.assertNotInstrumented(name, coverage.getName());return super.visitField(access, name, desc, signature, value);}

public class ClassInstrumenter extends ClassProbesVisitor 类;ClassInstrumenter类的调用:

@Overridepublic FieldVisitor visitField(final int access, final String name,final String desc, final String signature, final Object value) {InstrSupport.assertNotInstrumented(name, className);return super.visitField(access, name, desc, signature, value);}@Overridepublic MethodProbesVisitor visitMethod(final int access, final String name,final String desc, final String signature, final String[] exceptions) {InstrSupport.assertNotInstrumented(name, className);final MethodVisitor mv = cv.visitMethod(access, name, desc, signature,exceptions);if (mv == null) {return null;}final MethodVisitor frameEliminator = new DuplicateFrameEliminator(mv);final ProbeInserter probeVariableInserter = new ProbeInserter(access,name, desc, frameEliminator, probeArrayStrategy);return new MethodInstrumenter(probeVariableInserter,probeVariableInserter);}

********** Instrumenter类如下:

public byte[] instrument(final ClassReader reader) {final ClassWriter writer = new ClassWriter(reader, 0) {@Overrideprotected String getCommonSuperClass(final String type1,final String type2) {throw new IllegalStateException();}};final IProbeArrayStrategy strategy = ProbeArrayStrategyFactory.createFor(reader, accessorGenerator);final ClassVisitor visitor = new ClassProbesAdapter(new ClassInstrumenter(strategy, writer), true);reader.accept(visitor, ClassReader.EXPAND_FRAMES);return writer.toByteArray();}public byte[] instrument(final byte[] buffer, final String name)throws IOException {try {return instrument(new ClassReader(buffer));} catch (final RuntimeException e) {throw instrumentError(name, e);}}public byte[] instrument(final InputStream input, final String name)throws IOException {final byte[] bytes;try {bytes = InputStreams.readFully(input);} catch (final IOException e) {throw instrumentError(name, e);}return instrument(bytes, name);}public void instrument(final InputStream input, final OutputStream output,final String name) throws IOException {output.write(instrument(input, name));}private IOException instrumentError(final String name,final Exception cause) {final IOException ex = new IOException(String.format("Error while instrumenting %s.", name));ex.initCause(cause);return ex;}

从这个类的代码看,instrument(input,output,string)调用instrument(input,string),后者再调用instrument([],string),再调用instrument(classreader)

所以最终的出口在于最下面的instrument(input,output,string),下面是剩余部分代码:

public int instrumentAll(final InputStream input, final OutputStream output,final String name) throws IOException {final ContentTypeDetector detector;try {detector = new ContentTypeDetector(input);} catch (final IOException e) {throw instrumentError(name, e);}switch (detector.getType()) {case ContentTypeDetector.CLASSFILE:instrument(detector.getInputStream(), output, name);return 1;case ContentTypeDetector.ZIPFILE:return instrumentZip(detector.getInputStream(), output, name);case ContentTypeDetector.GZFILE:return instrumentGzip(detector.getInputStream(), output, name);case ContentTypeDetector.PACK200FILE:return instrumentPack200(detector.getInputStream(), output, name);default:copy(detector.getInputStream(), output, name);return 0;}}private int instrumentZip(final InputStream input,final OutputStream output, final String name) throws IOException {final ZipInputStream zipin = new ZipInputStream(input);final ZipOutputStream zipout = new ZipOutputStream(output);ZipEntry entry;int count = 0;while ((entry = nextEntry(zipin, name)) != null) {final String entryName = entry.getName();if (signatureRemover.removeEntry(entryName)) {continue;}zipout.putNextEntry(new ZipEntry(entryName));if (!signatureRemover.filterEntry(entryName, zipin, zipout)) {count += instrumentAll(zipin, zipout, name + "@" + entryName);}zipout.closeEntry();}zipout.finish();return count;}private ZipEntry nextEntry(final ZipInputStream input,final String location) throws IOException {try {return input.getNextEntry();} catch (final IOException e) {throw instrumentError(location, e);}}private int instrumentGzip(final InputStream input,final OutputStream output, final String name) throws IOException {final GZIPInputStream gzipInputStream;try {gzipInputStream = new GZIPInputStream(input);} catch (final IOException e) {throw instrumentError(name, e);}final GZIPOutputStream gzout = new GZIPOutputStream(output);final int count = instrumentAll(gzipInputStream, gzout, name);gzout.finish();return count;}private int instrumentPack200(final InputStream input,final OutputStream output, final String name) throws IOException {final InputStream unpackedInput;try {unpackedInput = Pack200Streams.unpack(input);} catch (final IOException e) {throw instrumentError(name, e);}final ByteArrayOutputStream buffer = new ByteArrayOutputStream();final int count = instrumentAll(unpackedInput, buffer, name);Pack200Streams.pack(buffer.toByteArray(), output);return count;}private void copy(final InputStream input, final OutputStream output,final String name) throws IOException {final byte[] buffer = new byte[1024];int len;while ((len = read(input, buffer, name)) != -1) {output.write(buffer, 0, len);}}private int read(final InputStream input, final byte[] buffer,final String name) throws IOException {try {return input.read(buffer);} catch (final IOException e) {throw instrumentError(name, e);}}

核心关键是instrumentAll这个方法,这个方法根据文件包是class还是zip,或者gz等,不同的加载方式。
jacoco loadclass入口类:CoverageTransformer

public class CoverageTransformerimplements ClassFileTransformer
{private static final String AGENT_PREFIX;private final Instrumenter instrumenter;private final IExceptionLogger logger;private final WildcardMatcher includes;private final WildcardMatcher excludes;private final WildcardMatcher exclClassloader;private final ClassFileDumper classFileDumper;private final boolean inclBootstrapClasses;private final boolean inclNoLocationClasses;static{String name = CoverageTransformer.class.getName();AGENT_PREFIX = toVMName(name.substring(0, name.lastIndexOf('.')));}public CoverageTransformer(IRuntime runtime, AgentOptions options, IExceptionLogger logger){this.instrumenter = new Instrumenter(runtime);this.logger = logger;this.includes = new WildcardMatcher(toVMName(options.getIncludes()));this.excludes = new WildcardMatcher(toVMName(options.getExcludes()));this.exclClassloader = new WildcardMatcher(options.getExclClassloader());this.classFileDumper = new ClassFileDumper(options.getClassDumpDir());this.inclBootstrapClasses = options.getInclBootstrapClasses();this.inclNoLocationClasses = options.getInclNoLocationClasses();}public byte[] transform(ClassLoader loader, String classname, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)throws IllegalClassFormatException{if (classBeingRedefined != null) {return null;}if (!filter(loader, classname, protectionDomain)) {return null;}try{this.classFileDumper.dump(classname, classfileBuffer);return this.instrumenter.instrument(classfileBuffer, classname);}catch (Exception ex){IllegalClassFormatException wrapper = new IllegalClassFormatException(ex.getMessage());wrapper.initCause(ex);this.logger.logExeption(wrapper);throw wrapper;}}boolean filter(ClassLoader loader, String classname, ProtectionDomain protectionDomain){if (loader == null){if (!this.inclBootstrapClasses) {return false;}}else{if ((!this.inclNoLocationClasses) && (!hasSourceLocation(protectionDomain))) {return false;}if (this.exclClassloader.matches(loader.getClass().getName())) {return false;}}return (!classname.startsWith(AGENT_PREFIX)) && (this.includes.matches(classname)) && (!this.excludes.matches(classname));}private boolean hasSourceLocation(ProtectionDomain protectionDomain){if (protectionDomain == null) {return false;}CodeSource codeSource = protectionDomain.getCodeSource();if (codeSource == null) {return false;}return codeSource.getLocation() != null;}private static String toVMName(String srcName){return srcName.replace('.', '/');}
}

核心的两条代码:transform

try{
      this.classFileDumper.dump(classname, classfileBuffer);
      return this.instrumenter.instrument(classfileBuffer, classname);
    }

********** 具体报错日志的分析:

java.lang.instrument.IllegalClassFormatException: Error while instrumenting class com/suning/srcdas/address/business/AddressBusiness.at org.jacoco.agent.rt.internal_6da5971.CoverageTransformer.transform(CoverageTransformer.java:93)at sun.instrument.TransformerManager.transform(TransformerManager.java:188)at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)at java.lang.ClassLoader.defineClass1(Native Method)at java.lang.ClassLoader.defineClass(ClassLoader.java:800)at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)at java.net.URLClassLoader.access$100(URLClassLoader.java:71)at java.net.URLClassLoader$1.run(URLClassLoader.java:361)at java.net.URLClassLoader$1.run(URLClassLoader.java:355)at java.security.AccessController.doPrivileged(Native Method)at java.net.URLClassLoader.findClass(URLClassLoader.java:354)at java.lang.ClassLoader.loadClass(ClassLoader.java:425)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)at java.lang.ClassLoader.loadClass(ClassLoader.java:358)at org.springframework.util.ClassUtils.forName(ClassUtils.java:250)at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:401)at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1432)at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1377)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:641)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:609)at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1484)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:425)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:395)at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:81)at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524)at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:149)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:606)at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:100)at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:515)at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:216)at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:143)at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:169)at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)at org.testng.TestRunner.privateRun(TestRunner.java:753)at org.testng.TestRunner.run(TestRunner.java:607)at org.testng.SuiteRunner.runTest(SuiteRunner.java:368)at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:363)at org.testng.SuiteRunner.privateRun(SuiteRunner.java:321)at org.testng.SuiteRunner.run(SuiteRunner.java:270)at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)at org.testng.TestNG.runSuitesSequentially(TestNG.java:1284)at org.testng.TestNG.runSuitesLocally(TestNG.java:1209)at org.testng.TestNG.runSuites(TestNG.java:1124)at org.testng.TestNG.run(TestNG.java:1096)at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:132)at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:193)at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:94)at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:147)at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
Caused by: java.io.IOException: Error while instrumenting class com/suning/srcdas/address/business/AddressBusiness.at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrumentError(Instrumenter.java:160)at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrumenter.java:111)at org.jacoco.agent.rt.internal_6da5971.CoverageTransformer.transform(CoverageTransformer.java:91)... 66 more
Caused by: java.lang.IllegalStateException: Class com/suning/srcdas/address/business/AddressBusiness is already instrumented.at org.jacoco.agent.rt.internal_6da5971.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:89)at org.jacoco.agent.rt.internal_6da5971.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:55)at org.jacoco.agent.rt.internal_6da5971.asm.ClassVisitor.visitField(ClassVisitor.java:272)at org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.readField(ClassReader.java:768)at org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.accept(ClassReader.java:689)at org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.accept(ClassReader.java:506)at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrumenter.java:84)at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrumenter.java:108)... 67 moreat org.jacoco.agent.rt.internal_6da5971.CoverageTransformer.transform(CoverageTransformer.java:93)at sun.instrument.TransformerManager.transform(TransformerManager.java:188)at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)at java.lang.ClassLoader.defineClass1(Native Method)at java.lang.ClassLoader.defineClass(ClassLoader.java:800)at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)at java.net.URLClassLoader.access$100(URLClassLoader.java:71)at java.net.URLClassLoader$1.run(URLClassLoader.java:361)at java.net.URLClassLoader$1.run(URLClassLoader.java:355)at java.security.AccessController.doPrivileged(Native Method)at java.net.URLClassLoader.findClass(URLClassLoader.java:354)at java.lang.ClassLoader.loadClass(ClassLoader.java:425)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)at java.lang.ClassLoader.loadClass(ClassLoader.java:358)at org.springframework.util.ClassUtils.forName(ClassUtils.java:250)at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:401)at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1432)at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1377)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:641)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:609)at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1484)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:425)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:395)at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:81)at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524)at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:149)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:606)at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:100)at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:515)at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:216)at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:143)at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:169)at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)at org.testng.TestRunner.privateRun(TestRunner.java:753)at org.testng.TestRunner.run(TestRunner.java:607)at org.testng.SuiteRunner.runTest(SuiteRunner.java:368)at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:363)at org.testng.SuiteRunner.privateRun(SuiteRunner.java:321)at org.testng.SuiteRunner.run(SuiteRunner.java:270)at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)at org.testng.TestNG.runSuitesSequentially(TestNG.java:1284)at org.testng.TestNG.runSuitesLocally(TestNG.java:1209)at org.testng.TestNG.runSuites(TestNG.java:1124)at org.testng.TestNG.run(TestNG.java:1096)at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:132)at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:193)at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:94)at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:147)at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
Caused by: java.io.IOException: Error while instrumenting class com/suning/srcdas/address/business/AddressBusiness.at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrumentError(Instrumenter.java:160)at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrumenter.java:111)at org.jacoco.agent.rt.internal_6da5971.CoverageTransformer.transform(CoverageTransformer.java:91)... 66 more
Caused by: java.lang.IllegalStateException: Class com/suning/srcdas/address/business/AddressBusiness is already instrumented.at org.jacoco.agent.rt.internal_6da5971.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:89)at org.jacoco.agent.rt.internal_6da5971.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:55)at org.jacoco.agent.rt.internal_6da5971.asm.ClassVisitor.visitField(ClassVisitor.java:272)at org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.readField(ClassReader.java:768)at org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.accept(ClassReader.java:689)at org.jacoco.agent.rt.internal_6da5971.asm.ClassReader.accept(ClassReader.java:506)at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrumenter.java:84)at org.jacoco.agent.rt.internal_6da5971.core.instr.Instrumenter.instrument(Instrumenter.java:108)... 67 more

先要加载一个类,但是这个类的成员声明了一个对象,所以先使用ClassInstrumenter.visitField 访问成员,访问失败所以为什么

打印了Instrumenter.instrument(Instrumenter.java:111)

访问成员为什么失败,因为这个成员对象创造之前,需要先加载这个类,然后创建一个类对象,再去创建一个对象的指针。

要加载这个成员对应的类就需要read class ,因为是离线模式(on-offline)所以调用了Instrumenter.instrument  input进来,然后再out出去;覆盖class文件。

jacoco 源码分析 class字节码植入的冲突问题相关推荐

  1. java 字节码分析_Java 字节码实践 - 解读

    最近刚看完 深入理解 Java 虚拟机 一书中的第 6 章 (类文件结构),便迫不及待地自己写一个小的 Demo,来自己分析一把 Java 源文件经过编译之后成为字节码文件到底是个什么东西?先由一个简 ...

  2. ASM字节码编程 | 用字节码增强技术给所有方法加上TryCatch捕获异常并输出

    作者:小傅哥 博客:https://bugstack.cn Wiki:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有所收 ...

  3. 【JVM】字节码与ASM字节码增强、Instrument实现类的动态重加载

    目录 字节码与ASM字节码增强 什么是字节码? 字节码结构 操作数栈与字节码 字节码增强 ASM 运行时类加载 Instrument JPDA与JVMTI instrument实现热加载的过程 字节码 ...

  4. 从0到1 Android安全学习之路 -- Java 字节码和 Dalvik 字节码

    Java 字节码和 Dalvik 字节码 概述 源代码样例 Java 字节码 Dalvik 字节码 总结 概述   本篇博客将讲述 Java 源代码到字节码,字节码转汇编,以及 Android 中 J ...

  5. java源码编译为字节码的流程

    1. 词法.语法分析和填充符号表 1.1 词法分析:将源代码的字符流转为Token集合,关键字.变量名.字面量和运算符都可成为Token,比如代码"int i = a + 2",那 ...

  6. 什么是字节码?采用字节码的最大好处是什么?

    什么是字节码? java中引入了虚拟机的概念,就是在机器和程序之间加入了一层抽象的虚拟机器.这台机器在各个平台中都给程序提供了接口. 程序只需要面向虚拟机编程,而不需要管理这套程序是否在什么平台执行. ...

  7. php 字节码查看,PHP字节码缓存和内置服务器

    Zend OPcache 1).从PHP5.0开始,内置了字节码缓存功能,名为Zend OPcache.因为PHP是解释性语言,PHP解释器执行PHP脚本时会解析PHP脚本代码,生成一系列的Zend操 ...

  8. 什么是字节码?采用字节码的好处是什么?

    Java中的编译器和解释器: Java中引入了虚拟机的概念,就是在机器和编译程序(idea等)之间加入了一层抽象的虚拟机.这台虚拟机器在任何平台上都提供编译程序一个共同的接口,所以就算在window. ...

  9. 【Java面试】什么是字节码?采用字节码的好处是什么?

    文章目录 编译语言与解释语言 什么是字节码? Java的编译器和解释器 Java 程序从源代码到运行一般有下面 3 步: 编译语言与解释语言 编译语言就是类似于C语言这种,在运行真正的代码之前先需要进 ...

最新文章

  1. Linux Shell编程入门
  2. 公司内部多表查询 sql在实现类的应用
  3. Android 数据存储与IO (一)
  4. (连通图 模板题 无向图求桥)Critical Links -- UVA -- 796
  5. 伪静态 全站php 跳到html,IIS下万能301跳转方法:URL伪静态重写+PHP301
  6. 蚂蚁金服 CEO 突然辞职!去向很意外。。。
  7. web聊天类数据库功能表结构如何设计?
  8. dumpDex脱壳教程
  9. non-local caffe2 编译
  10. java中map和表单字符串相互转换
  11. 小猫小狗玩数学-第14届蓝桥杯STEMA测评Scratch真题精选
  12. C语言%7.2d、%-7d、%7.2f、%0.2f的含义和区别
  13. 添加myenv至jupyter notebook kerne
  14. Lazy Prices公司年报内容变动碰上股价偷懒
  15. Windows 平台安装 MongoDB数据库(检测是否安装成功、启动和关闭MongoDB数据库)
  16. 用Python实现喷墨打印机定期清洗喷头
  17. 我眼中的王石(转 目光呆滞的润土)
  18. “人文素养老师”——马小平老师
  19. 点云编码是计算机视觉吗,本周新出开源计算机视觉代码汇总(含图像超分辨、视频目标分割、行人重识别、点云识别等)...
  20. 人工智能图片无损放大工具_借助这款最新AI图片无损放大工具,我把老板的头放大了4倍!【杰视帮】...

热门文章

  1. codelite在 ubuntu6.04下开启C++11支持
  2. tensorflow kears GPU CUDA Cudnn 各种版本问题
  3. ASSERT: “QGLFunctions::isInitialized(d_ptr)“ - Runtime Exception
  4. OpenCV, 名校机器学习相关课程
  5. python主线程有两个子线程、创建两个主函数_Python多任务之线程
  6. Git ----fatal: unable to access ‘https://gitee.com/***.git/‘: SSL certificate problem: unable
  7. 利用zookeeper实现分布式服务故障自动剔除/服务自动注册的思路
  8. node遍历给定目录下特定文件,内容合并到一个文件
  9. JavaScript常用内置对象之Array
  10. 《Python入门经典》——导读