I have a situation at the moment where I have:
Project A which is built into a fat jar using Maven assembly plugin.
Project B which uses the jar built in Project A. It is added to the project as a resource and launched in a separate process using a process builder.
I wonder if it's possible to achieve similar behaviour using just one Maven project. I.e build the jar containing only the classes and dependencies required for project A, and then build the rest of the project with the prebuilt jar.
Sorry if I'm not being very clear here.
This is against a few of Maven's core concepts:
One project, one model (POM). Two projects (A, B), two models (POMs).
There's one artifactId in a POM. What is a second artifact (jar) supposed to be named?
One project leads to one artifact. There is no additional "prebuilt jar" built within the very same project.
Dependencies are for the whole project (and possible sub-module projects). I'm not aware of how to "containing only the classes and dependencies required for project A".
Artifacts are stored:
in <project>/target temporarily
in the local Maven repository (default: ~/.m2/repository)
possibly in a remote Maven repository
... while resources are taken from <project>/src/main/resources during the build.
There might be some tricky solutions (which have possibly pitfalls, too) to achieve this if one thinks about it thoroughly. But I'd never ever recommend such.
Related
We have a EAR project which has a WAR project. Maven is used, so pom.xml. As typical of any project, this project also contains a big feature (say Job Scheduling "JBS") among many other features. As it is planned to retire this whole project in the near future, it is discouraged heavily to spend much on working on this project (whether bugs or enhancements).
Therefore, for the sake of running the (JBS) feature as a separate application, the whole EAR project was duplicated (also to save time/cost). As a result, all the Java packages and classes (necessary for JBS project) were duplicated. In this situation, if we update one or more classes in the main project, this (JBS) feature project/application gets outdated (and needs update).
The fact is that this JBS feature project ONLY requires many packages of Java classes (from the main EAR-WAR project), and do not require 99% of the web modules and others. I am removing all the unnecessary things from JBS project. Then I would like to create a JAR library with all the java classes, so JBS project can have a dependency on this JAR.
I do not know if it is a good idea to separate these classes out of the main project (to create another Java project). I would like to continue to have these classes as part of the main project. Then, it will be good, as and when one or more of these classes are changed, a new version of the JAR will be generated (right away). And the JBS project would then make use of this updated JAR.
How can we accomplish this? I understand, through maven, we can do a build/package jar/war/ear on a project of that nature. I am not an expert with maven (and did not learn it systematically).
But, is there a way to create one or more JARs additionally from inside WAR pom.xml? In other words: I mean pom.xml of WAR will create a WAR. In addition to creating a WAR, can maven help create additional JAR? Or can maven create two packages out of one pom.xml?
Or should I create a separate module in the main project with all these packages/classes, and have its own pom.xml to generate the necessary JAR? For this, most probably I need to modify the structure of the main project. I would like to avoid this unless there is no way out.
Can you advice?
It seems like the best thing for you would be to create a multi-module project that both contains the JAR and the other project. This way, you can easily change/build them together, but you create separate artifacts.
Very new to Maven, can someone please explain to me the difference between using maven modules vs just adding a dependency to your maven project to another maven project in your workspace? When would you use one over the other?
A dependency is a pre-built entity. You get the artifact for that dependency from Maven Central (or Nexus or the like.) It is common to use dependencies for code that belongs to other teams or projects. For example, suppose you need a CSV library in Android. You'd pull it as a dependency.
A Maven module gets built just like your project does. It is common to use Maven modules for components that the project owns. For example, maybe your project creates three jar files.
A dependency can be thought of as a lib/jar (aka Artifact in Maven parlance) that you need to use for building and/or running your code.
This artifact can either be built by your one of the modules of your multi module project or a third party pre-build library (for example log4j).
One of the concepts of maven is that each module is going to output a single artifact (say a jar). So in case of a complex project it is good idea to split your project to multiple modules. And these modules can be dependent on each other via declared dependencies.
See http://books.sonatype.com/mvnex-book/reference/multimodule-sect-intro.html for example of how a web app is split to parent and child modules and how they are linked.
One of the most confusing aspects of Maven is the fact that the parent pom can act as both a parent and as an aggregator.
99% of the functionality you think about in Maven is the parent pom aspect, where you inherit things like repositories, plugins, and most importantly, dependencies.
Dependencies are hard, tangible relationships between your libs that are evaluated during each build. If you think of your software as a meal, it's basically saying A requires ingredient B.
So let's say you're preparing lasagne. Then your dependency chain would look something like this:
lasagne
<- meatSauce
<- groundBeef
<- tomatoPaste
<- cheese
<- noodles
The key thing is, each of the above items (meatSause, groundBeef, cheese, etc) are individual builds that have their individual set of dependencies.
By contrast, the only section of your pom that pertains to aggregation is the modules section:
<modules>
<module>meatSauce</module>
<module>groundBeef</module>
<module>tomatoPaste</module>
<module>cheese</module>
<module>noodles</module>
</modules>
Aggregation simply tells your build engine that it should run these 5 builds in rapid succession:
groundBeef -> tomatoPaste -> cheese -> noodles -> meatSauce
The main benefit of aggregation is the convenience (just click build once) and ensuring the builds are in the correct order (e.g. you wouldn't want to build meatSauce before tomatoPaste).
Here's the thing though: even if you organize the libs as standalone projects without module aggregation, your build will still come out the same provided you build in the correct order.
Moreover, both Jenkins and Eclipse have mechanisms for triggering builds if a dependent project has changed (e.g. changing groundBeef will automatically trigger meatSauce).
Therefore if you're building out of Jenkins or Eclipse, there is no need for aggregation
I am a bit curious about how this works - if I have 5 module projects in a Maven multi-module project, can you import the content and packages into other modules without adding that project as a dependency? Or do you in-fact need the .jar (or a snapshot jar) in order to use structures/functions from other modules?
Thank you,
Inter-module dependencies (adding one module as a dependency in another module's pom.xml) is meaningful in the world of Maven (as a build tool, not an IDE). When you build your multi-module projects from command-line, you don't need concern the dependencies between each module yourself, Maven will topologically sort the modules such that dependencies are always build (hence generate the jar file) before dependent modules (so that it can reference generated jar file as a dependency).
This is not necessary (in theory) if you use IDE like Eclipse, as you can achieve the same result (adding one project as a dependency of another) by some manual settings in Eclipse Right click project and choose Properties -> Java Build Path -> Projects -> Add, which is automatically handled when Eclipse import your multi-module project, if you define inter-module dependency in pom.xml.
The question is why you want to do something unusual (without adding that project as a dependency) that you cannot gain any benefit from it.
I want to create a maven project, which has to depend on a non maven project which in turn depends on 2 other non maven projects. I do not have ownership of any of the other projects and it would not be possible for me to change anything in those projects let alone the structure to conform to the maven structure.
I asked if I could just get jars -- but was told that because of multiple levels of dependency, it would be "difficult" -- although I haven't understood why.
Is this possible or should I just abandon the use of maven to create my project and go with a regular project with jars in the lib folder?
Inxsible
If you can go with a regular project build that means you must have access to the other project's jar files?
It doesn't really matter how the other project builds them, you can still gain more control over your own build process by loading the jars you depend on into a Maven repository.
I'd suggest using one of the following repository managers:
Nexus
Artifactory
Archiva
They'll give you management screens to uploading 3rd party jars, they'll also a more efficient way to use other Maven repositories like Maven Central.
Once you've got your Maven build process working, you could encourage the other projects to automatically publish their versions into your Maven repo.
They could use the ANT tasks provided by the Maven or Apache ivy projects. Worst case you just continue to load their libraries until they see the light :-)
Recently I came across with the term 'artifact' in related to maven build tool...
Can someone please explain what it's meant by 'artifact' in software industry and specifically in maven.
Maven organizes it's build in projects.
An artifact in maven is a resource generated by a maven project. Each maven project can have exactly one artifact like a jar, war, ear, etc.
The project's configuration file "pom.xml" describes how the artifact is build, how unit tests are run, etc.
Commonly a software project build with maven consists of many maven-projects that build artifacts (e.g. jars) that constitute the product.
E.g.
Root-Project // produces no artifact, simply triggers the build of the other projects
App-Project // The application, that uses the libraries
Lib1-Project // A project that creates a library (jar)
Lib2-Project // Another library
Doc-Project // A project that generates the user documentation from some resources
Maven artifacts are not limited to java resources. You can generate whatever resource you need. E.g. documentation, project-site, zip-archives, native-libraries, etc.