Java project dependency on another project - java

I have a maven project (Proj1). In my java class I have to call method of another maven proj (proj2).
Here I get various compile time errors as that method is not available in my current project (proj1).
In order to resolve that I took whole method code and paste that method in my current java class.
Now that method is available in my project. But then that method again calls few other code from other classes which are again not available in my current project.
Again I needed to copy and paste all the dependent code from other classes.
This goes on and on and circular dependency is there so just wondered how I can resolve this error.
I have couple of options in order to resolve this.
Take source of all the classes from proj2 make a jar out of that and include that jar in my classpath
This solved few errors but then there are some classes from third party jars which still giving errors.
Now I am planning for 2nd option in which I have pom.xml for proj2.
I create build out of that. So that all the necessary jars will get downloaded from repository.
Output of this proj is again jar named proj2.jar.
Now my question is
If I include only proj2.jar in my code then will it resolve all the dependency?
OR I need to manually add all the jars in proj1 class-path which are there in proj2
OR I need to add src of proj2 as well as jars from proj2.jar?
OR is there any better way of doing this than the above mentioned options?

Make all you projects use maven. Add pom.xml to the root of your project with following header(I don't know your packaging structure so com.sachin is placeholder. You can ask IDE to add maven support for you):
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sachin</groupId>
<artifactId>Proj2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>My Proj2</name>
Add same header for Proj1 and add dependency from Proj1 to Proj2:
<dependency>
<groupId>com.sachin</groupId>
<artifactId>Proj2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
After maven build Proj2 will be added as jar dependency to Proj1.
if I include only proj2.jar in my code then will it resolve all the
dependency?
If your proj2.jar has pom.xml with dependencies that proj2.jar use - then yes they will be fetched during building of proj1 using maven.
Official documentation about Maven Dependency Mechanism

Related

Using custom packaging type as dependency in maven

I have created a custom packaging type in my maven plugin so that I can deploy files in this custom format.
E.g. I have a project that uses this format for packaging. The pom.xml has:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>mylib</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>mybin</packaging>
....
I am able to deploy successfully to a repository. But now I want to use this as a dependency in another project.
E.g. by adding something like this:
<dependency>
<groupId>com.example</groupId>
<artifactId>mylib</artifactId>
<version>1.0-SNAPSHOT</version>
<type>mybin</type>
</dependency>
This is working fine, also except that mybin format includes some nested resources such as jar files) that I would like to include in the classpath.
I so far I've attempted to programmatically extract the jars from inside a mojo and programmatically add it to the project using project.getModel().addDependency(systemJarDep), but this doesn't seem to be picked up by the compiler.
How can this be done in Maven?
It seems that this sort of thing cannot be done in Maven.
I am solving my problem by adjusting the format of my custom package type to be a jar file itself, with all of the classes that I want on the classpath directly inside it. The other sub-resources that I don't require on the classpath (at least by default) are bundled inside the META-INF directory.
This is not ideal, but it is an acceptable solution for now.

Project Dependency in Maven

I have two different maven projects - let's say ProjectA and ProjectB where ProjectA uses ProjectB.
These projects have seperate pom.xml files. I would like to create a dependancy inside the pom.xml of ProjectA and include ProjectB.
However, everytime I try to run as clean install it always fails and shows the following error.
[WARNING] The POM for database-manager:database-manager:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[ERROR] Failed to execute goal on project cumulus-certificate-generator-attestation: Could not resolve dependencies for project database-manager:database-manager:jar:0.0.1-SNAPSHOT: Could not find artifact cdatabase-manager:cdatabase-manager:jar:0.0.1-SNAPSHOT -> [Help 1]
where database-manager = ProjectB.
My dependency (inside ProjectA pom.xml) looks like this:
<dependency>
<groupId>database-manager</groupId>
<artifactId>database-manager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
I want to mention that I found a solution by including a "master" pom.xml that will include these two projects but this is not the solution as I have multiple pom.xml files and multiple projects.
If this question has already been answered, can you please point me the solution as I cannot find anything similar to this.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>database-manager</groupId>
<artifactId>database-manager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>database-manager</name>
Thanks!
First: - just read error message more carefully:
cumulus-database-manager:cumulus-database-manager:jar:0.0.1-SNAPSHOT
This is dependency which missed not your database-manager:database-manager
Your projectB database-manager has it.
When dependency missed - it means as #Sridhar said it is not in <your home directory>/.m2/repository folder and as well as it cannot be downloaded from any defined remote repositories.
if cumulus-database-manager is valid dependency
I assume you have to see at the beginning of Maven output, some messages like downlading artifact ... from ...<url> and then cannot be downloaded message.
In this case you will get cumulus-database-manager/cumulus-database-manager direcotry in your locam .m2/repository, but with no jar file in it.
Try to delete cumulus-database-manager directory from .m2/repository and run again to force Maven try to download it again and look at messages why it was not downloaded...
BTW if you need to build at the same time two projects when one depends on another - you have to have "master" pom, with both projects defined in modules element. Otherwise you have to build one after another manually, at least for the first time.

Maven dependency management benefits

I am not sure I really understand the strongest feature of Maven - Dependency Management.
When I am developing a project I need to add all dependencies while I am writing the code. Therefore when building the project with Maven I already have all dependencies downloaded.
What is the point of the Dependency Management then?
Thanks to Maven you do not need to download the dependencies and put it into the lib on Tomcat for instance. It is done automatically by maven. You can see directly in the pom.xml file all you dependencies and also other settings.
Dependencies management is just one of the main feature of Maven. I think you should ask yourself what are the addotional tasks (external libs, deployment, documentation etc...) you are performing in your project and see if Maven can help you on these tasks with its plugins.
Let's assume For your local you have downloaded all the necessary jars and kept in lib.Now you want to move your code into many machines.
So now you have to transfer all the files to another machine.
By mistake if you miss some jars while sending or let's say in future you want newer version of jar.So Do you like to send it to all the machines the jar and remove the older version from lib or write a configuration that automatically does all the things in one go.
Once the project gets bigger you will feel the real essence of Maven.It's just the pom.xml you need to take care all the jar management.
Maven's dependency management makes most sense in an environment where you work on multiple projects, across multiple dev machines and more than one dev.
Imagine the simplest of scenarios:
Project_1
\lib
\log4j.jar
Project_2
\lib
\log4j.jar
Project_3
\lib
\log4j.jar
While you are developing you will need to copy paste the log4j.jar file to all of those projects, which translates to extra disk space used locally and on any SCM you may use, and need to go into each project and define it as a library (add it to the classpath). If you want to change the version of the jar you need to repeat the process.
If you use Maven, all you need to do is
define an online repository (example Maven online repo)
create a pom for your project:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>COM.MY.COMPANY</groupId>
<artifactId>NAME_OF_PROJECT</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
Most IDE's already have seamless integration with Maven and no further hassle is needed. And the above steps are only executed once.
Some additional references:
Why maven? What are the benefits?
Why should we use Maven?
Maven Dependency Plugin Example

How to add jar file dependency in pom.xml

I have an application that depends on 2 jar file :
OperatorInterface.jar
Operator.jar
I want to build my project using Maven structure. I've followed the Maven site tutorial to create the structure like so:
mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=source.app -DartifactId=project
I've put my source file FileProcess.java in E:\project\src\main\java\source\app.
FileProcess has dependency in 2 external .jar files but I don't know how to define this dependency in pom.xml.
Here is the content of the pom.xml so far:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>source.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Can anyone help me?
First thing you need to install your jars in your maven local repository. You can follow the official tutorial here:
https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
During the installation you will have to choose your own artifactId, groupId and version. You can choose whatever value you want but remember them because you will need those to include your jars in the pom.
After that you can include them in your pom.xml adding these lines under the tag dependencies for each library to include:
<dependency>
<groupId>your_group_id</groupId>
<artifactId>your_artifact_id</artifactId>
<version>your_version</version>
</dependency>
In the case when the JARs in question are your own code rather than third-party, the best approach is to "mavenize" the projects that build them as well. After you do that, running mvn install on those projects will place them in your Maven local repository where they will be available to other local Maven projects who declare them as dependencies.
Avoid adding them to yourpom.xml file straight. When you add .jars using this process, they will automatically reflect in your pom.xml
Steps are -
1. Right click on your project in the file explorer in your eclipse.
2. Go to build Path option.
3. Select configure build path
4. Chose the Libraries tab in the window that appears.
5. Add your .jar file externally.
6. Click ok and come back to your project interface
Update your maven project by pressing Alt+F5 and restart eclipse. Your problem should be solved.
I would take the following route since this is for corporate use. This is the hard and ultimately portable way that sets you up for future Maven usage as it is intended to be done.
1) make those dependent jars Maven projects (because then you can easily version-manage them too using Maven)
2) use a local repository manager and deploy your own projects to it using Maven release management through either the mvn:release plugin, or use a build server such as Hudson to automate the release process with a simple button press which I can highly recommend setting up.
https://maven.apache.org/repository-management.html
http://maven.apache.org/maven-release/maven-release-plugin/
3) mvn:release the dependency jars to your local repository manager so they will be available for other Maven projects
4) you're actually done, when you have a local repository where your deploy your own snapshot and release artifacts to, then your maven build can find your own maven modules and include them in the application dependencies - if you don't forget to configure the repository in the project's pom of course. And your build server if you have one can find them too.
The easy/lazy route is as suggested to manually install the jars in your local .m2 folder where Maven caches dependencies that it downloads, but it is absolutely not a portable solution that will stand the test of time. It won't work when somebody else needs to work on this project until they too install the jars locally. Or if its only you, you need to redo it every time you checkout the project on another computer / as another user. Also you need to update the jars each and every time you make changes to them, everywhere the project is checked out. You may need to do specific setup steps to get it working in an IDE, should you inevitably choose to start to use one.
However if you are having a time-pressure problem, then I would certainly go ahead and do that as a temporary workaround solution to be able to get going.

Having a maven project build its own dependencies?

With maven is it possible to have a top-level project who's packaging type is "war" which will build itself and all of its dependent modules (packaged as jar) and have the build generate a project.war file?
Much of the documentation examples and other examples I've seen often use a top-level project with packaging type of "pom" and the project only serves the purpose of tying the modules together. Can I avoid this?
So basically I need something which is effectively like declaring a <module>my-module</module> for maven to build, and in that same POM, declaring a <dependency>...my-module's artifact...</dependency> on that same module which needs to be built. Maybe a plugin as someone already suggested?
Update: In other words (to simplify the problem): If I have project A and project B, where project A depends on project B - is there a way for me to execute a build on project A and also have it automatically build project B (and include project B as its dependency - creating projectA.war which contains projectB.jar)?
super_aardvark suggested correct way but,
For requirement I would suggest following structure It is suitable and good structure also :
Consedering ProjectA as project-webapp , ProjectB as project-core
You can have following structure :
Your Grand Project :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.project</groupId>
<artifactId>project</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Project Repository System</name>
<description>Project Repository System R2</description>
<modules>
<module>project-core</module>
<module>project-webapp</module>
</modules>
</project>
Your WebApp Project:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>com.mycompany.project</groupId>
<artifactId>project</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>project-webapp</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Project Web Application</name>
<description>Project Repository</description>
<dependency>
<groupId>com.mycompany.project</groupId>
<artifactId>project-core</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
</project>
Your Core Project:
<project>
<parent>
<groupId>com.mycompany.project</groupId>
<artifactId>project</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>project-core</artifactId>
<version>2.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Project Core</name>
<description>ProjectCore</description>
</project>
Your Directory structure should look like:
-------Grand Parent.pom
|
|--------project-webapp
| |
| project-webapp.pom
|
| -------project-core.pom
|
project-core.pom
From parent pom execute mvn clean install it will build both the web-app and core project
That's not really what a top-level project is for. Your WAR project has dependencies, which are the artifacts (e.g. jars) that will be included in the WAR (in WEB-INF/lib) when you run 'mvn package'. Your WAR project pom can have the top-level project as its parent, but it shouldn't be the parent of its dependencies. You may want to have that top-level project be the parent of both the WAR project and of the JAR projects that are dependencies in the WAR.
This is not possible in Maven 1, 2 or 3.
I'd recommend to give up this idea, because Maven's whole purpose is to enforce standardized development process. Don't fight the structure, just create a parent POM module and make the WAR module and other dependencies underneath it.
When you have a multi-module project and you're doing work in several modules simultaneously it can be tedious and error-prone to make sure all the necessary dependencies are updated.
In my situation, I would like my build system to detect changes and only build the modules that are necessary. One way this might be possible with maven is for someone to write a custom plugin that does this, which doesn't seem insurmountable given there are already complex plugins available, like the maven release plugin.
Others have already mentioned the aggregation pom concept, which is repeatable and does produce the necessary artifacts. But sometimes you end up building more than you really need to.
Maven profiles can help and here's a good article in that regard:
Using Aggregate and Parent POMs
Also note in the article the concept of the batch pom, which I was not previously aware of.
Remember, mvn clean install will push your artifact into your local repo. So if module A depends on module B, as long as your local repo has the latest build of module B then you should be all set. So, if there were an external tool that was watching for changes to module B and automatically built it when there were and pushed those changes into the local repo then when module A was rebuilt it would pick up those changes. There are continuous integration (CI) tools that can do this, like Jenkins. But you would need a local install to have this work directly with your local repo. It's still an option, though.
Another option would be for the CI environment to push your builds to an external maven repo (or even one you setup locally with something like Nexus). Then you setup your CI builds to pull from that location as well.
So, there are solutions that rely on other tools or potential plugins to do what you want - just depends how much time and effort you want to invest to get it all setup. But, once you get over that hurdle you'll have a system (and knowledge and experience) that you can use on all your projects, not to mention you'll be familiar with how many development shops/teams work.
I would recommend researching continuous integration and continuous delivery for more information and ideas.
In parent pom, you have to define a sequential order of modules to be compiled. You can add a war packing module to the last in that list. It will simply aggregate all previous compiled code together.
Not really - (Well, I can think of a couple of ways, but I'd not use them as they're convoluted and go against the basic ethos/practices of Maven).
Don't forget that the other purpose of the top-level pom is to provide a single point to set common details such the particular versions of dependencies used in the modules of the project.
NetBeans has an option that allows you to do exactly this with Maven projects but I don't know any pure Maven solutions. I think that the task is more suited for an IDE, because it knows for what depended projects you have the code (based of what projects you have opened in the workspace). How would Maven itself differentiate between a dependency that you want to build and one that needs to be fetched from the repository. And for those that need to be built, where should it look for the source code?
Anyway, another solution to the problem, that I used successfully a few times, is to create a simple shell script that navigates to your projects folders and starts the build then it waits for it to finish then proceeds to the next project and so on.

Categories