[ https://issues.apache.org/jira/browse/MCOMPILER-320?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16329558#comment-16329558 ]
David M. Lloyd commented on MCOMPILER-320: ------------------------------------------ Thanks for the feedback. A new "compile-only" scope would definitely be good but it would not solve either of my two present immediate use cases. Case 1 is that if you build a project in Java 9, and use {{--release=8}} (i.e. {{<release>8</release>}}) then the sun.misc and sun.reflect packages are not included in the class path. They must be stubbed, however you absolutely do _not_ want to have the stubs appear in _any_ context other than the exact compilation, otherwise severe problems will occur: the JVM could even crash. A new scope _almost_ solves this, but not quite, because you might only want to include the stub in one execution. What if you have more than one? Which brings us to case 2. Case 2 is that currently the best way of building an MR JAR can be done by way of multiple executions. But in order to do this, the overlay executions must include, on the class path, each earlier execution's output classes. Here's an example of both cases being done at once; this is using a version of the plugin which contains my proposed patch: {code:xml} <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.1-SNAPSHOT</version> <executions> <!-- here I'm disabling the default compilation because of my parent POM; you could make the Java 8 step be the default though --> <execution> <id>default-compile</id> <phase>none</phase> </execution> <!-- this compiles the base layer; however the release=8 option prevents sun.misc from being visible --> <execution> <id>compile-java8</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <release>8</release> <buildDirectory>${project.build.directory}</buildDirectory> <compileSourceRoots>${project.compileSourceRoots}</compileSourceRoots> <outputDirectory>${project.build.outputDirectory}</outputDirectory> <!-- this dependency is manually downloaded using the dependency plugin below --> <additionalCompilePathItems> <additionalCompilePathItem>${project.build.directory}/sun-misc.jar</additionalCompilePathItem> </additionalCompilePathItems> </configuration> </execution> <!-- this compiles the Java 9 layer; sun.misc is not a problem here but we also need to include our base classes in the compilation --> <execution> <id>compile-java9</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <release>9</release> <buildDirectory>${project.build.directory}</buildDirectory> <compileSourceRoots>${project.basedir}/src/main/java9</compileSourceRoots> <!-- we can output directly into the appropriate target directory; this works out nicely --> <outputDirectory>${project.build.directory}/classes/META-INF/versions/9</outputDirectory> <!-- here is where we include the base classes --> <additionalCompilePathItems> <additionalCompilePathItem>${project.build.outputDirectory}</additionalCompilePathItem> </additionalCompilePathItems> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <!-- here we download the stubbed out sun.misc and sun.reflect into target for use up above --> <execution> <id>fetch-misc</id> <phase>generate-sources</phase> <goals> <goal>get</goal> <goal>copy</goal> </goals> <configuration> <artifact>org.jboss:sun-misc:1.Final-SNAPSHOT</artifact> <outputDirectory>${project.build.directory}</outputDirectory> <stripVersion>true</stripVersion> </configuration> </execution> </executions> </plugin> {code} This makes use of several basic defining features of Maven: the ability to have multiple executions, the usage of maven-dependency-plugin to fetch dependencies by way of specific goals, etc. The only missing piece is the ability to add class path entries. I am enormously skeptical that a practical high-level solution to MR JARs will appear in Maven _ever_. Even if I was wrong and it would happen, I am extremely confident that it would be inadequate for any non-trivial case, and furthermore, as a maintainer of many frameworks, I contend that most any case where a framework _would_ require MR JARs would be a non-trivial case. This is due to the fact that some of the key APIs that are motivating factors in producing MR JARs - namely sun.misc.Unsafe and sun.reflect.ReflectionFactory - have to be specially handled in the way that I have done above. It is unlikely that a single compiler plugin pass, no matter how enhanced, would be able to cope with this situation, nor would it be able to cope with any other situation where different layers of the JAR would require different compiler parameters - a situation that seems inevitable to me. I don't think there is a better solution to MR JAR than the one I've worked up in this example. We could maintain our own fork of this plugin, but that would be a bit ridiculous: nothing in this proposed change opposes what I would call a rational interpretation of the spirit of Maven's design, or of the design of javac. > Allow additional class path items to be given during compilation > ---------------------------------------------------------------- > > Key: MCOMPILER-320 > URL: https://issues.apache.org/jira/browse/MCOMPILER-320 > Project: Maven Compiler Plugin > Issue Type: New Feature > Reporter: David M. Lloyd > Priority: Major > > At present it is very difficult to include additional class path items during > compilation that are not dependencies. But this is a very useful capability, > especially when doing partial builds, MR JARs, JDK API stubbing, including > dependency items that cannot be included in any other build phase or > execution, etc. > This enhancement and pull request are to request the addition of a > {{additionalCompilePathItems}} property in CompilerMojo or > AbstractCompilerMojo which includes additional filesystem paths in the > compilation class path. -- This message was sent by Atlassian JIRA (v7.6.3#76005)