Alternate solution to the Maven Shade plugin in order to deploy a list of shared libraries in the Cargo plugin? - maven

I need to execute non-regression tests on a system made of a set of Web Applications and shared libraries. I currently use the Maven Cargo plugin in order to deploy this system on an Apache Tomcat Web Container.
Up to now, the shared libraries, which are also used in the production environment, were referenced in a Maven BOM file, and then "imported" by other Maven projects. For instance, they are imported by the Maven projects that take care of the distribution of the software.
However, this approach does not work with the Cargo plugin, because this plugin seems not to support the import of the materials declared in a BOM file. As a workaround to this issue, I've used the Maven Shade plugin in order to produce an "uber" jar with all these shared libraries. This is working perfectly well, but I'm not 100% satisfied with this workaround, for the same reasons as those reported in What is the maven-shade-plugin used for, and why would you want to relocate java packages?
As there any other alternate approach to this issue (EAR not supported in our environment) ?

Related

Why is there no easy way to create a fat Jar with Gradle?

I am building a lightweight API client that depends on a few small libraries. I need to package it into a jar to distribute to clients. I am using IntelliJ, Gradle, Kotlin ecosystem.
Gradle offers a task to build a Jar but it doesn't include the dependencies and therefore is useless to me. Isn't building source+dependencies more common than just source? Why is there no such task? Seems like most of my google searches point me to self-written Gradle tasks that would bundle dependencies together.
Or is there a different practice on how usually libraries are built?
I am assuming the JAR in question is private by your usage of client.
There is a plugin from the community that is often recommended: https://imperceptiblethoughts.com/shadow/
Gradle also offers a plugin to create a fat/uber JAR, but is more geared towards applications hence the name: Application plugin. -- more on this later
If you intend for the API client JAR you are creating to be used in other clients' build tools such as Maven or Gradle, then you should not create a fat JAR and instead document that in order for clients to include your API client JAR, they will need to provide X, Y, Z dependencies as part of their build process. You will also need to communicate the minimum or maximum supported version your support. This gives the client the flexibility to provide X, Y, Z dependencies from wherever they want. This is where the jar task provided by Java plugin comes into play.
But if you do not want clients to override the version of internal dependencies your client uses, then yes, you will need to build a fat JAR that includes those dependencies which is where the Shadow plugin (linked above) comes into play.
Now back to the Application plugin, underneath, it applies the Distribution plugin which provides the capability to create a fat JAR. However, this is not commonly used for reasons I do not know and instead you will find the aforementioned Shadow plugin used more commonly. This is probably because the Shadow plugin offers more control on how the dependencies are packaged in the fat JAR such as relocating packages.

After making a Gradle groovy jar library how to make it re-usable for multiple local projects?

Here I read about how to make a Groovy library .jar ... i.e. pretty much the same as making a Groovy (standalone) project. But I'm not clear what you do then with the resultant .jar...
Say I have two Eclipse "proper"/"standalone" projects (I'm using Groovy for everything) and I want them to share a third Gradle library project of mine as a dependency, which is merely a library of classes... how are my standalone projects expected to find the latest .jar version of the library which they're both using...?
My expectation would be that somehow these versions of the library .jar would have to under GRADLE_USER_HOME (i.e. same location as all other dependency .jars).
Then I would assume that in the build.gradle of both standalone projects you'd have a line like
compile 'mylibrary:mylibrarymodule:3.+'
... of course the first part of these compile directives normally involves a "domain name in reverse" ... and this is normally used by a repository like Maven. How does it work with something which doesn't need to be published?
NB at the time of writing I don't have a Maven account as such and have no idea whether "publication" for re-use of a local common library project like this is essential or not.
Naturally, when I distribute versions of my standalone projects they will need to be packaged up with the library .jar in question.
A link to a how-to for a case like this would be more than welcome: I haven't found it under gradle.org.
If you are developing by yourself, you can use maven-publish plugin to publish your artifacts to local maven repository(you don't have to install maven for this) and on your dependent project you can simply say use mavenLocal repository for dependencies.
If you are on a company, I suggest installing a repository manager and deploy your artifacts to this repository so others can use. You can use their respective plugins to deploy easily. (Gradle Artifactory Plugin, Gradle Nexus Plugin, these are just deployment plugins, you have to setup respository manager to. There are other repository management tools also.) Doing the above process from CI server is the preferred way.
To use latest version of a dependency, you can use Gradle Versions Plugin. If the versioning happen often, using snapshot versions also a possibility.

Confused with maven assembly plugin vs build-helper-maven:attach-artifact

I'm a bit confused between maven assembly plugin and build-helper-maven plugin.
I've also read in the maven documentation that The assemblies/archive created by the Assembly Plugin gets deployed during the deployed phase.Hence, they can be deployed to the remote nexus repositories.
The purpose of maven assembly plugin is to archive many things into one(say in tar.gz format).
However, the attach-artifact goal present within build-helper-maven plugin has the same role i.e.archiving,installing and deploying the artifact.
With that being said,why would anyone use both of them together? I've seen people using both of them together. Isn't one of the plugins an alternative choice of the other?
Kindly advise.
If you use maven-assembly-plugin you can create as you already mentioned any kind of archives (range from very simple to very complex structures) they will be by default be attached to your project which means they will be deployed into remote repositories in one go if you do mvn deploy with no supplemental configuration.
The build-helper-maven-plugin is intended to add an artifact (one goal of this plugin) which is usually not generated by Maven itself which most of the cases is a smell. If people using them together (in the use case to create an archive and attach it) this makes no sense.
Apart from that the build-helper-maven-plugin can also be used to add other source directories for example for scala, kotlin projects (other goals for example add-source etc.)
So those plugins are not alternatives they have different intentions/use cases.

Artifacts with jar packaging which could be become bundles too accordind to some profile

I would like to ask you some hints about the proper way to configure maven in the following scenario:
I have some artifacts which are currently packaged as jar, but they have maven-bundle-plugin too because I want them become OSGI bundles, nevertheless I didn't change their package to bundle because it exists the case that I want build them as jar (or war sometimes).
To use maven-bundle-plugin with package jar I have followed this chapter and all worked fine, but now I'm considering to package them with bundle, to gain the full features of maven-bundle-plugin and because my default deploy is to OSGI.
So I would like to know if packaging artifacts as bundles but using them in a not OSGI container may results in troubles, what do you think? Thx
If you build your bundles using the alternative and newer plugin bnd-maven-plugin then it is not necessary to change the packaging type.

MAVEN - generating jboss 7 (or EAP 6.x) modules from dependencies

I would like to ask, if there is some maven plugin (or another way) to generate jboss modules hierarchy (with modules.xml files) from maven dependencies (or in list of libraries for such a maven plugin) ?
I have found this plugin :
https://www.smartics.eu/confluence/display/SJBMMP/smartics+JBoss+Modules+Maven+Plugin;jsessionid=3CA5AE2D1DEB5DFB62C1E64692EDCAB6
But documentation / usage pages seem to be offline (or for some reason I cannot open page).
Thank you very much for your help !
I have tried SMARTICS plugin plugin and it created for each maven module special JAR file with ALL dependencies in it.
It is like using maven assembly plugin but all libraries are packed in standalone jar which can be placed into own jboss module. Than in your application : jboss-deployment-structure.xml you reference to this librari (e.g. jar file) and application has all libraries provided.
But splitting dependencies into own directories and generating modules.xml is not possible (confirmed by JBOSS EAP support).
I will create standalone maven project (something like "JBOSS-modules BOM project") which will generate such structure (this structure will be ready for usage on jboss).
I just would like to add an introduction to the mentioned plugin for Maven:
https://www.smartics.eu/confluence/display/BLOG/2013/10/18/Maven+Plugin+to+generate+a+Modules+Directory+for+JBoss+AS+7
The article includes screenshots that help new users to get an idea on how the plugin generates separate modules.
(I would like to comment to your answer, but unfortunately I'm some points from being entitles to do so :( )

Resources