Monday, October 6, 2008

Maven 2, the Java Attach API, and JMockit

JMockit looked like it would be useful in testing so I thought I might try to get it into the central Maven 2 repository since others appeared already to be using it (at least in late 2007/early 2008). Had quite a bit of fun today trying to get it to work though, and although I got it to compile after some code mods and writing and testing a pom.xml for it, the tests failed. I'm working with the developer to see if he can assist. (He said it was ok for me to package it and put it in central.) Here's what I did: 1. Downloaded JMockit 0.94. 2. Created a pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <name>JMockit</name>
    <version>0.94</version>
    <description>JMockit</description>
    <packaging>jar</packaging>
    <url>https://jmockit.dev.java.net/</url>
    <licenses>
        <license>
            <name>MIT License</name>
            <url>http://www.opensource.org/licenses/mit-license.php</url>
        </license>
    </licenses>
    <scm>
        <connection>scm:cvs:pserver:cvs.dev.java.net:/cvs:jmockit</connection>
        <developerConnection>scm:cvs:pserver:cvs.dev.java.net:/cvs:jmockit</developerConnection>
        <url>https://jmockit.dev.java.net/source/browse/jmockit/main/</url>
    </scm>
    <developers>
        <developer>
            <name>Rogério Liesenfeld</name>
            <email>javamockit at yahoo.com</email>
        </developer>
    </developers>
    <dependencies>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm-all</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.5</version>
        </dependency>
        <!-- com.sun.tools.attach.* -->
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>tools</artifactId>
            <version>1.6</version>
            <scope>system</scope>
            <!-- OS X 10.5+ - must first change version of java in utilities/Java Preferences -->
            <systemPath>/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar</systemPath>
            <!-- everything else -->
            <!--
                <systemPath>${java.home}/../lib/tools.jar</systemPath>
            -->
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
3. Moved the source (main/src/*) into the Maven 2 default format (src/main/java/*) just to make things easier. Also moved the test source (main/test/*) into the Maven 2 default format (src/test/java/*). And I moved a test file out of main and under test. 4. Change all references in code from org.objectweb.asm2.* to org.objectweb.asm.* since that is the standard asm package. Rogério probably did that so that only the classes that were needed from dependencies were part of the JMockit jar to keep it light, and to avoid conflict with other versions of asm. But, it was easier to use the regular asm package so that I could just rely on the one in the central Maven 2 repo. 5. Changed two references where classpath separator was ";" instead of System.getProperty("path.separator") as noted by Ivan Koblik in http://markmail.org/message/ggprsfmbkwgc57rj 6. Ran the following as noted in http://maven.apache.org/guides/mini/guide-central-repository-upload.html mvn repository:bundle-create It compiles! However, almost all tests fail with:
java.lang.RuntimeException: Required Java Agent library not found in the classpath: jmockit.jar
        at mockit.internal.JDK6AgentLoader.getJarFilePathFromThisJVMClasspath(JDK6AgentLoader.java:77)
        at mockit.internal.JDK6AgentLoader.loadAgent(JDK6AgentLoader.java:39)
        at mockit.internal.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:51)
        at mockit.internal.Startup.verifyInitialization(Startup.java:165)
        at mockit.Mockit.redefineMethods(Mockit.java:68)
        at integrationTests.CTest.testPublicIntNoArgs(CTest.java:59)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
        at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:138)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:125)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:132)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:290)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:818)

No comments: