First off, I'm a long time user (and beneficiary) of StackOverflow, but this is my first question. I've done plenty of searching on this topic, but most of the articles I've turned up talk about generating JAR files, not working with 3rd party JARs from the Maven Central repo which I don't really have the power to fix. The few solutions I've seen floating around aren't really acceptable.
The problem is that most of the jaxb JARs found in the Maven Central repository contain classpath entries (in the MANIFEST.MF file) that point to dependencies, and those dependencies are specified with relative paths -- typically assuming that dependency bar.jar exists in the same directory as foo.jar.
This is fine if you have all your JAR dependencies in a single lib directory, for example. But:
- Maven wants to maintain its own local repository, so every single packaged JAR lives in its own directory (with each version in a separate subdirectory).
- Maven JARs are typically named with the version info embedded in the filename, whereas the classpath entry in MANIFEST.MF specifies the dependency with just the base filename (no version).
The net result is an error message like this:
[ERROR] bad path element "C:\Users\rpoole\.m2\repository\com\sun\xml\bind\jaxb-impl\2.2.11\jaxb-core.jar": no such file or directory
One solution is to write a script or small app to go through all the JARs and strip out the classpath info from the embedded MANIFEST.MF file. But that is not very clean, and requires an extra step before doing the actual build.
Another potential solution is that some newer published versions of the JARs in question have supposedly fixed this classpath problem, so therefore use the latest and greatest. Unfortunately, this app I'm working on is legacy, and is being developed for a 3rd party, so I can't update the dependencies beyond a certain version. So far, all the jaxb JARs that I have poked into seem to have issues.
Is there a way to tell Maven to ignore the embedded classpath in the JAR and only rely on Maven's own dependency resolution? I've tried things like reordering dependencies, but that doesn't work (or moves the build problem from one subproject to another).
One additional annoyance: There is a "blessed" Maven repo we have that seems to let the build complete with no problem, but so far I've been unable to figure out why this particular set of JARs builds OK. I suspect someone may have gone in and tweaked some JARs or POMs manually, but there's scant information, and diff tools aren't really helping much.
Regardless, the project should build from scratch.
What would be nice is if I could specify something like an exclusion block in the pom.xml for the subproject that's breaking, but for dealing with a JAR's embedded classpath instead of Maven's own transitive dependencies (specified by groupId/artifactId).
Edit: Apparently, some people believe that this is impossible, and that Maven ignores the Class-Path entry in Manifest.MF. However, this is a known issue, as discussed in this StackOverflow article. There's also another good article which explains some of the history of this a bit better.
The problem is that I can't go through the JARs and edit the MANIFEST.MF files on each as part of the build process. That's just not a practical approach, even if automated by script. I need a solution that actually will work for code that is already in production. These issues were supposedly fixed in later versions of the JARs in question, but I may not be able to use newer versions of those.
Additionally, one of the proposed fixes is to add -Xlint:-path
to the compiler args, which suppresses the error message. However, the build simply fails at another point for me, so at first blush this does not appear to be a good solution either. I'll be trying this again because according to this, the syntax for compiler arguments inside POM files is a bit wonky.