Search code examples
javacompilationinria-spoon

What is the --precompile flag supposed to do?


I am using Spoon to generate code on annotated classes so I can reduce the boilerplate and code repetitions on a project I am working on.

As the project is pretty small I was looking for ways so I do not have to split the whole thing into two or even three different projects that have to be compiled in order so my AnnotationProcessor is available in

Looking at the Spoon documentation I have found the --precompile flag, which, as I understand it, should precompile the whole source and add it to the classpath so Spoon will find the processor and other stuff at runtime.

But according to the errors I get when running it, it does not seem to work and I am still missing the processor even though I've added the option.


[INFO] --- exec-maven-plugin:1.5.0:java (execute-spoon) @ JHTML5 ---
12:29:50.454 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - output: spooned
12:29:50.456 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - destination: C:\Data\CrumbleWorks_java\JHTML5\spooned-classes
12:29:50.457 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - source classpath: null
12:29:50.457 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - template classpath: []
12:29:50.466 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - output: spooned
12:29:50.466 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - destination: C:\Data\CrumbleWorks_java\JHTML5\spooned-classes
12:29:50.466 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - source classpath: null
12:29:50.467 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - template classpath: []
12:29:50.467 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - compiling sources: []
12:29:50.539 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - compile args: [-encoding, UTF-8, -cp, .;/C:/Data/CrumbleWorks_java/JHTML5/target/classes;/C:/Data/Maven/repo/fr/inria/gforge/spoon/spoon-core/5.4.0/spoon-core-5.4.0.jar;/C:/Data/Maven/repo/org/eclipse/jdt/org.eclipse.jdt.core/3.12.0.v20160516-2131/org.eclipse.jdt.core-3.12.0.v20160516-2131.jar;/C:/Data/Maven/repo/com/martiansoftware/jsap/2.1/jsap-2.1.jar;/C:/Data/Maven/repo/commons-io/commons-io/1.4/commons-io-1.4.jar;/C:/Data/Maven/repo/org/slf4j/log4j-over-slf4j/1.7.21/log4j-over-slf4j-1.7.21.jar;/C:/Data/Maven/repo/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar;/C:/Data/Maven/repo/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7.jar;/C:/Data/Maven/repo/org/crumbleworks/forge/crumbutil/crumbutil/0.1.0/crumbutil-0.1.0.jar;/C:/Data/Maven/repo/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar, -d, C:\Data\CrumbleWorks_java\JHTML5\spooned-classes, -1.8, -proc:none, -preserveAllLocals, -noExit, -enableJavadoc, .]
12:29:50.790 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - compiled in 323 ms
12:29:50.792 [spoon.Launcher.main()] INFO spoon.support.StandardEnvironment - Spoon version 5.4.0
12:29:50.792 [spoon.Launcher.main()] INFO spoon.support.StandardEnvironment - running Spoon...
12:29:50.792 [spoon.Launcher.main()] INFO spoon.support.StandardEnvironment - start processing...
12:29:50.792 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - building sources: []
12:29:50.792 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - built in 0 ms
12:29:50.792 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - building templates: []
12:29:50.792 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - built in 0 ms
12:29:50.793 [spoon.Launcher.main()] DEBUG spoon.support.StandardEnvironment - model built in 1
[WARNING]
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:294)
        at java.lang.Thread.run(Thread.java:745)
Caused by: spoon.SpoonException: Unable to load processor "org.crumbleworks.forge.jhtml5.spoon.AttributeProcessor" - Check your classpath. Did you use the --precompile option?
        at spoon.support.QueueProcessingManager.addProcessor(QueueProcessingManager.java:79)
        at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.instantiateAndProcess(JDTBasedSpoonCompiler.java:169)
        at spoon.Launcher.process(Launcher.java:719)
        at spoon.Launcher.run(Launcher.java:665)
        at spoon.Launcher.run(Launcher.java:106)
        at spoon.Launcher.main(Launcher.java:99)
        ... 6 more
Caused by: java.lang.ClassNotFoundException: org.crumbleworks.forge.jhtml5.spoon.AttributeProcessor
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at spoon.support.QueueProcessingManager.addProcessor(QueueProcessingManager.java:77)
        ... 11 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.202 s
[INFO] Finished at: 2016-10-31T12:29:50+01:00
[INFO] Final Memory: 14M/284M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.5.0:java (execute-spoon) on project JHTML5: An exception occured while executing the Java class. null: InvocationTargetException: Unable to load processor "org.crumbleworks.forge.jhtml5.spoon.AttributeProcessor" - Check your classpath. Did you use the --precompile option? -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Full maven error output

Alas this line is what confuses me...

Caused by: spoon.SpoonException: Unable to load processor "org.crumbleworks.forge.jhtml5.spoon.AttributeProcessor" - Check your classpath. Did you use the --precompile option?

...because yes, I did use the --precompile option. Thank you for asking


<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>${exec-plugin.version}</version>
    <executions>
        <execution>
            <id>execute-spoon</id>
            <phase>process-sources</phase>
            <goals>
                <goal>java</goal>
            </goals>
            <configuration>
                <classpathScope>compile</classpathScope>
                <mainClass>spoon.Launcher</mainClass>
                <arguments>
                    <argument>--with-imports</argument>
                    <argument>--processors</argument>
                    <argument>org.crumbleworks.forge.jhtml5.spoon.AttributeProcessor</argument>
                    <argument>--enable-comments</argument>
                    <argument>--precompile</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

Maven plugin declaration to run spoon using the exec-maven-plugin (which executes any java executable)


So: What is the --precompile flag supposed to do?
Respectively what am I doing wrong?


edit:
Here's a simplified example with a maven-pom and a readme describing how to run and show without using maven: https://github.com/CrumbleWorks/Spoon-Precompile-Issue


Solution

  • The --precompile option compiles the source code given as input so that for all CtTypeReference objects, an actual class can be obtained with getActualClass(). In addition, it also enables getActualClass() for any CtType.

    (this allows for mixing Spoon's reflection with Java's reflection in the same analysis or transformation)