I've got this dependency in my pom.xml
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.18</version>
<type>pom</type>
</dependency>
And in my module-info.java file I have the following
requires transitive kernel;
which produces the following warning, "Name of automatic module 'kernel' is unstable, it is derived from the module's file name."
What can I do to get rid of this warning?
I tried changing it to
requires transitive com.itextpdf.kernel;
but then I get the following error, "com.itextpdf.kernel cannot be resolved to a module"
I tried a bunch of other similar lines of code but nothing worked. What can I change the code to in order to remove the error/warning?
itext7 currently isn't modular.
You can contact the developers and ask them to make it modular.
In the meantime, complex, non-modular systems like this are difficult to use from a modular project. Even if you get that to work via the automatic module system or hacking in module info via something like moditect, it pretty much destroys any potential benefit of the project being modular, and it runs the software in a way it was never designed to work.
So, make your project non-modular:
remove the module-info.java from your project.
source the javafx modules using either:
VM arguments pointing adding them to the module path OR
from a JRE/JDK distribution that includes them, e.g. BellSoft Liberica "Full JDK" or Azul Zulu "JDK FX".
For further instructions on working with non-modular JavaFX projects, see the getting started documentation at: openjfx.io.
I am not sure what "not modular" means but how can that be true if the itext7 website gives maven dependencies to incorporate into your pom.xml?
Non-modular means that you don't define a module-info.java in your project.
Read understanding modules and the documentation I linked at openjfx.io to understand the basics of the JavaFX module system and how it can be used in a JavaFX application.
Maven modules and Java Platform modules are different things, they have the same name "module" but one is a build-time definition and the other is a runtime definition. Also, a maven dependency is just a dependency, it is not a Maven module or a Java Platform module. Though you can depend on artifacts built by a maven module and you can execute those artifacts through the Java Platform module system (if they are compatible with it).
itext7 is not built as a Java Platform module. The software has no module-info.java and it does not define an automatic module name for itself either. Given that your software is depending on non-modular software, your software should not be modular either (in my opinion).
Related
I have three Java projects. The first is an application, com.foo:foo-application:1.0.0, and the second is a module used as a dependency to that application, com.foo:foo-framework:1.0.0. The third is a Maven plugin authored by our team, com.foo:foo-plugin:1.0.0.
My intention is that any project, e.g. foo-application, which uses classes available in foo-framework must also validate that it has used those classes correctly, where said validation is enforced by foo-plugin.
Is there a way to enforce this behaviour within foo-framework's POM.xml, whereby any Maven module which declares it as a dependency in its own POM will have foo-plugin executed as part of its build lifecycle?
No (at least no way that I'm aware of).
when you declare a dependency on something, youre declaring a dependency on its output artifacts (and transitively their dependencies as optionally described in that artifact's pom.xml file). There's no place in a pom file to force anything on the build importing it - the build importing it may not even be a maven build.
it appears you may be able to do something similar via other tools though - for example checkstyle supports discovering rules from dependencies on the classpath (not exactly what you want and depends on users of your library running checkstyle configured just right)
We're currently developing a Grails plugin that is meant to be a shared library of goodies for several different applications. This plug-in does the management around GORM and caching and, as such, it includes both the hibernate plug-in and the cache and cache-ehcache plugins. Hibernate and cache-ehcache plug-ins both want to import the ehcache-core jar dependency, but with different versions. The version of ehcache-core that I want is the one in the cache-ehcache plug-in so I've configured my BuildConfig.groovy like so:
compile(':hibernate:3.6.10.10', { excludes 'ehcache-core' })
compile ':cache:1.1.8'
compile ":cache-ehcache:1.0.4"
When running tests in this plug-in everything works just fine. However, once I include this plug-in in one of my real applications the excludes directive seems to be ignored and the transitive dependency on the hibernate plug-in starts pulling in ehcache-core. Having two versions of ehcache-core breaks many different aspects.
I've checked the grails dependency-report for my applications and it shows the chain of dependencies from my app -> my utility plugin -> hibernate plugin -> ehcache-core intact. The same dependency report run on the plug-in itself just points to the hibernate plug-in and then stops with no dependency on ehcache-core.
Anyone out there have any ideas as to why the dependency exclusion works while running the plug-in, but not while running the application that depends on the plug-in?
This is due to the change to the Maven/Aether dependency manager library. It's somewhat less buggy than Ivy and significantly faster, but is missing a lot of features that many of us are used to. One easy fix is to switch back to the Ivy resolver. You would only need to do that for the plugings when publishing, but not necessarily when using them since you need a defailed .pom file with exclusions listed so the consuming dependency manager knows what to ignore. If you use Aether the .pom files only include dependencies.
EDIT: I was focusing on the correctness of the pom files, and or course exclusions like this should work (although it'd be better to have correct poms and not have to force every user to fix this on their end.)
The issue might be that your group or name are different (e.g, "cache" vs. "ehcache"), and then they cant evict/exclude another. Or the jar might be coming from a different dependency and they exclusions are not global. There may be a way to set a global exclusion, but I don't know of one and there's nothing in the docs.
I have a maven multimodule project that has one parent pom-project and a bunch modules. One of these modules is the "main module" that has all the libraries shaded into it. All other modules depend on that module and use the provided libraries.
The main module is a Bukkit plugin that loads the other modules as extensions. These extensions are loaded all with their own classloader, but the loaded classes are shared between the loaders to be able to depend on each other. They are also able to depend on other Bukkit plugins, as their parent classloader is Bukkit's PluginClassLoader that also shares the loaded classes between plugins to allow interaction.
That's where the problems start: Different plugins may use the same library, but the classes of that library might get loaded by different classloaders which causes LinkageErrors and other problems.
My idea to solve that problem was to relocate the libraries in the main module via maven-shade-plugin. That works as expected with libraries that are only used by the main module. However relocating libraries used by the other modules causes runtime ClassNotFoundExceptions, because the modules still search for the normal package name instead of the relocated one.
Then I tried to change the imports to the relocated packages, but my IDE (IntelliJ) doesn't find the classes.
Has anyone an idea on how to solve this relocation problem? Or maybe different approaches on the classloading issue?
5 years later in a very similar context (Bukkit -> SpongeApi) I encountered this problem again, but this time I found the (probably only satisfying) solution:
The main module had its shaded version as the main artifact, so dependents could only see relocated classes and were unaware of the original classnames. This made no difference in our case, as the main module is a provided dependency anyway, but it also prevents consumers from accidentally using relocated classes directly. IntelliJ does not care for the relocations, so it was unaware of the new relocated classes. Attaching the shaded version as a secondary artifact (shadedArtifactAttached option set to true) makes the dependencies visible to the dependents again.
The dependent modules have to apply the same relocation rule as the main module, so the plugin corrects the classnames to the ones available at runtime.
This way IntelliJ is not aware of the relocations but it also doesn't need to be aware. If necessary, the relocations can be configured in a parent pom for consistant rules across all projects.
I had almost exactly the same problem you have/had (judging from the age of this question). Although I don't have a cleaner solution for the libraries overriding other plugins' versions, I do have a workaround for IntelliJ not recognizing relocated classes.
To stop it from complaining, I added the shaded jar (with the relocations) as IntelliJ library to the target module.
You can do this like so:
Go to File > Project Structure... > Modules > (target module) > Dependencies
Select the shaded jar using Add (green +) > 1. Jars or directories....
You should now see the shaded jar in the libaries list
Although it seems to work at first glance, this solution workaround has a few caveats:
Non-relocated classes are still visible to code through Maven's module dependency and if you happen to use them, you'll only see that upon compiling with Maven. (You could remove the module dependency, but it gets readded every time you reimport your pom)
You'd have to update the jar path every time you change your project's version if you include a version number in your jar file name (Workaround: Specify a static project.build.finalName)
When you add new methods or change signatures, you need to compile the library module again. (This can be worked around by creating a separate module for shading dependencies - That would actually also resolve the file name issue)
We have a Maven built Netbeans 7.1 rcp application that successfully mixes OSGi modules (packaging: bundle) and Netbeans modules (packaging: nbm) by wrapping the OSGi modules in Netbeans module wrappers. We want to migrate from using these wrappers to using the OSGi modules directly to simplify the build. There are around 30 wrapper, osgi module pairs and I would like to tackle the removal of the wrappers, one module pair at a time.
However when we replace a specific wrapper dependency with its osgi dependency in a modules pom that depends on it, and use the
<useOSGiDependencies>true</useOSGiDependencies>
in the nbm-maven-plugin configuration. Any other dependencies to other wrappers suddenly fail to build with transitive dependencies not available at runtime error.
Project uses classes from transitive module [xxx] which will not be accessible at runtime.
-- where [xxx] is the name of the OSGi module.
Of course I can fix the build by replacing the wrapper dependencies with the OSGi modules they were wrapping, but that escalates the size of the migration task considerably.
Once Ive got a build by "fixing" these transient dependencies the OSGi module that I picked to migrate appears successfully in a new cluster “extra”.
But at runtime the rcp fails to find the other osgi modules because, I guess, elsewhere in the build, they are still being referenced through wrappers.
Is there any way these wrappers and direct OSGi dependencies can co-exist? Or do I have to migrate all of the Netbeans wrappers to OSGi in one go?
Many thanks,
Phil Wilkinson.
Looks like theres no way to do this one wrapper at a time, its all-or-nothing with useOSGiDependencies. :(
You can change them to useOSGiDependencies=true one module at a time.
A detailed step-by-step guide would probably be too long for an answer, so here are some general rules for this to work:
Use nbm-maven-plugin version >= 3.11. Lower version has some bugs.
NBM wrapper's OpenIDE-Module & OpenIDE-Module-Specification-Version must match the wrapped bundle's Bundle-SymbolicName & Bundle-Version respectively.
If the bundle has package versioning, that has to be copied into the NBM wrapper's MANIFEST.MF as Netigso-Export-Package.
I have a Maven project multimodule project. Some of the modules create custom packaging for the libraries produced by the other modules. The packaging being used has its own suite of versioned dependencies that I need to play nice with.
As an example: my parent POM might have an entry for e.g. commons-codec:commons-codec 1.4, my "core-lib" POM includes it as a dependency (sans explicit version), and I want to make sure my packaging module bundles in the right version. However, the specific type of custom packaging that I'm using also needs e.g. log4j:log4j 1.2.15, and I want to make sure that when my packaging module runs, it also bundles the correct log4j version.
Here's the wrinkle: the example POM I'm working from for "project that makes {custom packaging}" uses a parent that's provided by the custom-packaging team. If I use their parent, I lose the version info for commons-codec. If I use my parent, I lose the version info for log4j.
Now, ordinarily if I ask "how do I make A and B depend on the same version", you'd answer "make A and B have the same parent, and include a dependencyManagementsection in the parent". My problem is, I need A, B, and C to depend on the same version, but I don't have any control over C.
I think this is what Maven "mixins" are meant to address, but of course they don't exist yet. In the meantime, what I've been doing is picking one parent, then copy-and-pasting the dependencyManagement section from the other POM, with a comment saying "make sure you keep this up to date". Obviously this is an ugly, ugly hack, but I haven't found another way to keep current with both sides.
What about using the assembly plugin to pack up your artifact with all its dependencies and having your packaging module run on that instead? Then you're not trying any pom magic. It's just a matter of one project using the artifact from another project, like usual.
For now, I'm going to accept the answer of "this is one of the really sucky things about Maven". Maybe this question can get updated when Maven 3.1 finally launches.
Could you not activate multiple profiles which have their own dependency section pulling in the required libraries when enabled. This allows some nice flexibility due to the ways that profiles can be activated.