I am having difficulties understanding HOW maven compiler plugin works under the hood post java 8 (i.e. JDK 11).
(I know how to operate it to work with JDK 11 (using <release> element), but I am interesting (and confused) as to HOW it works behind the scenes)
When working with pure JDK 11 javac, I can give it the --classpath argument and have all the jars listed there be treated as Unknown module.
I can also give javac the --module-path argument, and have all the (non modular) jars appearing there to be treated as Automatic module(s).
But, when working with maven project, using the maven-compiler-plugin with JDK 11, how does it compile my code ? are all the dependencies are in the classpath ? or in the module-path ? perhaps both ? what maven uses to distinguish between them ?
I have read the maven-compiler-plugin documentation, that referred me to the plexus compiler project (and could not find there much to be honest). I expected to be able, eventually, see the actual command line that maven compiler plugin uses when invoking javac for me and its various used arguments. I tried to invoked it with verbose=true and did not get anything useful as well..
All in all, I could not find anything useful on that stuff ; All references explains how to operate compiler plugin as a black box, nothing about how it actually works internally. :(
Anyone knows or has a good reference to a proper documentation\explanation on the above ?
Update:
Following #khmarbaise comment, -X shows a lot of debug information, among it a detailed list of what jars\classes are used in the class-path and which are in the module path.
One strange thing remains though:
I am compiling maven module A which is a java module as well (it has module-info.java file). It seems that A's classes (...\A\target\classes folder) is given to the class-path argument. Any idea why ?
Related
When running the package phase in maven, I get the following warning after the javadoc has been generated:
javadoc: warning - The code being documented uses modules but the packages defined in http://docs.oracle.com/javase/7/docs/api/ are in the unnamed module.
What does this mean?
Something similar happened to me. I got the following error message when employing the maven-javadoc-plugin.
[ERROR] javadoc: warning - The code being documented uses modules but the packages defined in http://docs.oracle.com/javase/7/docs/api/ are in the unnamed module.
I had copied and pasted example xml into my POM verbatim which employed version 2.9.1. When I updated to the current version (currently 3.4.0) this error went away.
IDK if you are using this plugin. If so, check the version. If not, perhaps you can troubleshoot your plugins to determine which, if any, are triggering this error message. If there is a specific culprit, check that it is a current version.
My project is set to compile at a compatibility level for Java 11. I don't have any references to Java 1.7, AFAIK. I've run across various situations using Maven where older versions of Java are the default, so I think in any configuration situation that allows you specify a Java version, it's maybe safest to simply go ahead and do so, even if it is optional.
I am working on migrating multi module java project into maven. Now for most of them i migrated to maven.
Finally i am aware my project have lot of unnecessary jars included, and i want to clean them up.
I know maven has plugin command, mvn dependency:analyze. Which works very well.
dependency:analyze analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared. based on static code analysis.
Now my question is that, how can i remove reported unused and declared dependency for cleanup purpose. It could be possible those jars were getting used at runtime and my code will compile perfectly fine after removing but blow up at runtime.
An example: mycode compile with one of opensource library antisamy.jar but it require batik.jar at runtime. And mvn dependency:analyze reports me to remove batik.jar.
IS my understanding correct or i need expert inputs here.
Your understanding seems to be correct.
But I'm not sure why you'd think that there is a tool that could cover all the bases.
Yes, if you use stuff by reflection, no tool can reliably detect the fact that you depend on this class or the other.
For example consider this snippet:
String myClassName = "com." + "example." + "SomeClass";
Class.forName(myClassName);
I don't think you can build a tool that can crawl through the code and extract all such references.
I'd use a try-and-fail approach instead, which would consist of:
remove all dependencies that dependency:analyze says are superfluous
whenever you find one that was actually used, you just add it back
This could work well because I expect that the number of dependencies that are actually used by reflection to be extremely small.
I'm setting up a (java) maven project that depends on a library (Jettison, among others) that is in the Maven repo. Jettison, in turn, depends on stax. I need to run a tool (Jar Jar Links) on stax (to change the namespace). How do I alter the rules for a transitive dependency in a maven project? My transitive dependencies are being included in my target folder using the copy-dependencies goal (I assume this is how things are usually done). I assume that this is the point where the plugin would be run on the transitively-generated artifact.
Extra question: I don't need this at this point but how would I go about altering the source in the transitive dependency? I can get the jar of the source with mvn dependency:sources but, from there, I'm not sure what the right approach is.
Victory!
Seems at least two people are even more clueless about Maven than me so let me explain what I'm doing before I report the fix at the bottom of this post (spoiler alert: it looks to be a bug in JarJar).
Android uses Java but its missing a lot of the java core (specifically, javax classes). The Android DEX compiler (which converts .jars to Android .dex files) won't even allow you to compile things in the java.* or javax.* namespace because it'll (usually) break stuff. However, in some (many) cases, there are routines that you might want to include -- specifically because they are used by existing libraries. The most legendary is StAX, which is why Google posted an example of how to include it here in the Dalvik repo's wiki. The example uses JarJar... with ant. Transitive dependencies are not really an issue when you aren't using a repo so they are not addressed in the wiki.
I was able to get JarJar to run on my source with Maven but without changing the namespaces in the dependencies (and transitive dependencies), that's worthless. Hence my question.
I thought that the copy-dependencies plugin might be useful for... copying the dependencies and running a transforming plugin in the process. Copying dependencies is mentioned as a step in the official "Maven in 5 minutes" doc so it seemed like a good start but maybe the the people who wrote the official docs don't know how to use it :-) . Either way, it it didn't help -- there is no simple way I could see to transform the jars as it copies.
Using the verbose spew from Maven, I was able to see that Jar Jar was in fact processing my jars properly... and then throwing out the result. It would have packaged the converted classes from the transitive dependencies in my artifact with the rest of my code but, instead, it "Excluded" them. Jar Jar parameters are basically undocumented and most of the tags aren't even listed in the docs but all of the examples I could find use a section with wild-cards that tell it what classes to hold onto. At least I thought (think?) that's what the section is for. Instead, it seems to randomly throw out stuff. Basically, the section is busted. For example, I had:
<keep>
<pattern>com.example.**</pattern>
</keep>
...thinking that this would keep classes that began with com.example. Wrong. It keeps whatever the hell it wants. I tried a million things in that spot until one worked:
<keep>
<pattern>*.**</pattern>
</keep>
This only keeps the classes I wanted -- the classes it updated and the originals of the ones that it didnt touch. Note that ** doesn't even work. This is version 1.8 of the JarJar plugin (the version most poms Ive found use).
Back to work.
I have a massive Java 6 migration planned for Maven projects that are currently using JDK4 and JDK5.
In doing so, i'd like to script as much as possible. One thing I'd like to script is to replace all Maven references to a JDK4 or JDK5 to JDK6.
The question is, what are all the ways a Maven file can reference JDK?
Here are the ones I know of, listed as XPath's:
//plugin/artifactId[.='maven-compiler-plugin']
//maven.compiler.source
//maven.compiler.target
EDIT: Found another one
/project/profiles/profile/activation/jdk
EDIT: User added one
The aspectj-maven-plugin has source and target configuration.
Am I missing any?
I had a situation in my project where two dependencies relied on a different version of a jar. Just showing the dependency tree only showed the newer version and where it was used, so I ended up going through the POM files (I had an idea where it might be) to find the source.
My question: is it possible to get a dependency tree that includes these dependencies that were removed (showing why they were removed). I seem to recall the m2eclipse plugin can do it, but I'd prefer a command line tool (since I'm not using eclipse).
edit:
Specifically, I already tried the dependency tree, including running with full debug output (-X). As far as I could tell, it doesn't show when it's masking these dependencies.
Just try the maven-dependency-plugin use the tree goal to look at the tree of dependencies. But it might be a good idea to use Eclipse via m2e plugin for such problems.