How to correctly import a Maven dependency that I altered and re-built into an existing project? - maven

I have a Maven dependency, pulsar-log4j2-appender, which I forked and changed the source code because it was throwing exceptions in my project.
After changing the source code, I ran the maven package command to build the jar and imported it into my project (in Intellij: Project Structure | Modules | Dependencies | Add JARs or directories...).
However, when I run the application, it seems like it's not able to find that dependency because the Pulsar appender which I declared in my log4j2.xml file isn't being configured.
Am I importing the JAR properly? I'm wondering if the JAR needs to be within the org.apache.pulsar namespace to be imported properly.
For example,
This is what the dependency looks like unaltered:
And this is what it looks like when I modify and build it myself:

If you modify the code from an open source project you should change both the groupId and the artifact id. If you do not you will have problems and future developers will say your name in ways you do not want to hear.
Changing these are necessary so that Maven knows to use your version instead of the publicly available version. Also, when people look at your project and see the groupId and artifactId from the "real" project they will naturally assume that is what is being used (which is why they will curse you if that is not the case). In addition, you will have to do something convoluted to get Maven to use your dependency reliably.
The practice I have followed is the prepend "com.mycorp", where mycorp is my employer's name, to the groupId and add mycorp into the artifactId. The only downside to this is that you must ensure that the "real" artifact's coordinates are not referenced as a dependency or as a transitive dependency or else you will have duplicate classes on the class path.
Finally, your best bet is to create a pull request for Apache Pulsar with your fix so that other people experiencing the same problem you are get the benefit of it.

Related

Is it possible to force a Maven plugin to be included in a project from a dependency of that project?

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)

How does the Intellij Idea change the scope of dependencies?

I found this function in Project Structure in Intellij Idea:
It seems that this UI can manually change the scope of the dependencies. However I found that it does not change the pom.xml file, so how can it manages to change the scope?
Besides, what is the corresponding operation in Linux?
That particular view is geared more towards projects which lack dependency management from something like Maven or Gradle, and will not interfere with either. In fact, this particular listing is built based on those dependencies and exclusions.
If you want to change the scope of your dependencies in a project that already contains Maven and Gradle, look to do so in their respective files (pom.xml / build.gradle).

Maven dependency aliasing

I've just noted that my war contains both woodstox-core-asl-4.4.1.jar and woodstox-core-5.0.2.jar. They are two different version of the same library, but the library changed both groupId and artifactId. Furthermore both are included in my war as transitive dependencies by two different modules of my project.
I know that I can use exclusions to remove the old version of the library but in this case I should also explicitly "include" the new version in case that module would be used alone (that is not with the other one that includes woodstox-core-5.0.2.jar).
I don't like this solution. Is there any way to declare that woodstox-core is an alias of woodstox-core-asl so that Maven includes only one of these jars?
A similar problem affects old Spring 2.x that published both an all-in-one artifact and smaller separated artifacts. However I think that the most common issue is the one related to artifacts that change their groupId and/or artifactId.
There is no way to do this. Maven doesn't understand the concept of aliases. If it did, then that would open the door to a whole other kind of dependency hell.
What you've described -- adding an <exclusion/> for the <dependency/> for all dependencies that need it and then explicitly adding a new <dependency/> for the renamed artifact -- is the only way you can achieve this at the moment.

Multiple Maven modules with dependency on a JAR

In my multi-module Maven project, suppose I have two modules, car and horse. They both depend on a JAR file, transport.jar, a file not available in any online Maven repositories. As such, I need to find a way to make these modules depend on a file found somewhere in the project folder structure.
From what I understand, the default Maven solution would be to manually register the JAR file in the local repository. While this would work on a development machine, it breaks on the build server, which clears its local repository before each build.
I've been searching online on how to do this on and off for a while and found some helpful things, but nothing that completely works.
For instance, a common answer is to add a dependency to the file using <scope>system</scope>. However, not only do others claim that it's extremely bad practice to do so, it also doesn't work on the build server. (On a side note, I would also like to point out that using absolute paths to the JAR is also out of the question due to, again, it being built on several different machines.)
A more useful method I found was to define a local repository in the POM file, pointing towards the path file:${project.basedir}/lib. (Such as in this article) Unfortunately, if I place the JAR and repository definition in the car POM, I cannot successfully add a dependency to the JAR in horse. I've tried both with and without an additional reference to car in horse, as well as defining a second repository in horse, pointing to file:${project.basedir}/../car/lib. This problem would also remain if I tried to make a third module, transport-lib, specifically for wrapping the JAR dependency.
I could most likely add the JAR file to both modules and define two separate module-local repositories, but I really don't want to unless I have to due to the need to keep the two (often updated) JARs in sync etc.
So, my question is as follows: Can someone give me a confirmed-to-work method to have two modules depend on the same JAR file inside the project, given the parameters and restrictions mentioned?
Best solution is to use a repository manager like Archiva, Artifactory or Nexus and install that artifact into the repository manager. Afterwards you can use this artifact directly in your pom files without any issue.
Don't use the scope system, cause it will cause other problem after a release for other etc.

how can I find the artifactId and version information for '"libopencv_java.so" and "libnative_camera_r2.2.2.so" in pom.xml in Maven?

I've searched for hours but no artifactId and version information for "libopencv_java.so" and "libnative_camera_r2.2.2.so".. I know how to add dependency into pom.xml to be included in lib/armeabi in .apk, but I just cannot find the correct information.. The pox.xml keeps complaining
"Missing artifact org.opencv:libnative_camera_r2.2.2:so:2.2.2
Missing artifact org.opencv:libopencv_java:so:1.0"
Thank you so much~!!
These are native non-Java libraries. They aren't normally handled by Maven. If you would like to use static objects in your module, I suggest you have something like ${basedir}/lib and place your static libraries in there. Add the directory as a <resource/> as well and have it included in you jar. I think it should be possible to load the .so from within the jar. This is one option.
Another option would be, (if you really, really must re-use the .so-s across modules), to extract them to a separate module and have your module depend on that one.
Either way, you'll need to do quite a bit of magic, which isn't covered by Maven by default.

Resources