Ant jar library in maven project - java

We started to develop a new web application project and decided to use Maven. This project will use some older internal ant based jar library, so I decided to use Nexus to create our internal repository. I deployed the library to Nexus and linked pom.xml to the new repository and set the dependency to newly created artefact. Maven builds war without problems, I can deploy it on server and launch. So far, everything is working fine.
But now, when I try to call some code of the library, I got a NoClassDefFoundError exception.
java.lang.NoClassDefFoundError: HTTPClient/HTTPConnection
at com.logica.imfplus.authentication.client.HttpConnection.connect(HttpConnection.java:217)
at com.logica.imfplus.authentication.client.HttpConnection.<init>(HttpConnection.java:135)
at com.logica.imfplus.authentication.client.LoginController.getResponse(LoginController.java:402)
at com.logica.imfplus.authentication.client.LoginController.login(LoginController.java:169)
at com.logica.imfplus.authentication.client.AuthClientAPI.internalLogin(AuthClientAPI.java:416)
at ...
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassNotFoundException: HTTPClient.HTTPConnection
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
... 38 more
I googled little bit and added dependency manually to the missing library.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
But I got another various NoClassDefFoundError exceptions. All problem seems to be more complex.
I think I understand the problem: The jar library has it's own internal dependencies defined by ant, but they are not visible for maven so they are still missing. But I don't know, how to solve it.
If I am right, I was thinking of examining all those internal dependencies manually and add them to pom.xml. But it seems like dirty solution and I don't feel safe about it. I also don't want to add mess to my pom.xml, if I don't have to. Is there any cleaner way, how to do it? Can maven examine and resolve internal dependencies of non-mavenized jar library defined earlier by ant?
I am still learning with maven, so solution is maybe obvious. I still didn't find anything useful.
EDIT:
Solution found and working. I created a new pom.xml with defined dependencies as suggested and (manually) uploaded to Nexus. Now transitive dependencies are correctly resolved and downloaded by maven. Here it is fyi. (There was in fact only one dependency to define.)
<?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.logica.imfplus.authentication</groupId>
<artifactId>authenticationClient</artifactId>
<packaging>jar</packaging>
<version>1.3.1.0_8</version>
<name>IMFplus authenticationClient</name>
<dependencies>
<dependency>
<groupId>net.sf.grinder</groupId>
<artifactId>grinder-httpclient</artifactId>
<version>3.9.1</version>
</dependency>
</dependencies>
</project>
I still got some ClassNotFoundException, but it is probably caused by some collision in libraries, this is different story.

The ideal way to do this is to rebuild your internal library with a pom of its own where you specify all its dependencies. Then you should point that pom.xml to your nexus repository and deploy it (as in mvn deploy). This way, the pom.xml will get published too in nexus and any application using the maven dependency will download too every dependency that your legacy library carries with it.

In general, you should only be deploying your internal artifacts to your internal Nexus. 3rd party artifacts should be obtained via your internal Nexus that acts as a Proxy Repository to the public Nexus repositories. These days, you can normally find most 3rd party artifacts in a public repository somewhere.
When it comes to Maven, it uses what's called transitive dependencies, which in short means that if artifact A depends on artifact B and you create a new artifact that depends on A, you'll also depend on B.
For this to work it's important that artifact A is built with Maven because the dependencies are captured at build time. The alternative is that you manually deploy the pre-built artifact, in which case the dependency information has been lost and you'll have to define it yourself by creating a pom for the 3rd party artifact.
Assuming the dependencies are correct (you can list them with mvn dependency:list), when you build a WAR with Maven, all the compile and runtime dependencies will be included in the WEB-INF/lib directory.

A good solution for this problem is to create a pom.xml for the ant project that declares the dependencies correctly and use the aether ant tasks to deploy the jar from the Ant build to the Nexus instance.
Then you can use the Ant built Jar from Maven like any other dependency and it will even have the correct transitive dependencies managed automaticall.y

Related

Pom.XML Maven Build Dependency of POM Only Looking for Jar

GIVEN:
I have an in house tool built with gradle that includes a dependency that is only a POM file which in turn then includes a bunch of other dependencies. No jar for this particular dependency by itself. The tool builds.
I have a maven project with a pom.xml file that I want to include this tool in because of all the company specific methods needed for some processes. I added the dependency with the type of pom and when I build it fails.
ERROR:
[ERROR] Failed to execute goal on project <MYPROJECT>: Could not resolve dependencies for project <MYPROJECT>:jar:0.0.326: <com.pom.only.dependency>:jar:7.0 was not found in <Company Repo where this POM file exists> during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of <company repo> has elapsed or updates are forced
REQUEST:
I have tried making the tool a fat jar in the hopes it would not need this. But it does. The my project builds without this tool jar so I know it is this jar that brings in the dependency. I just have no idea how to resolve this.
ALMOST CODE EXAMPLE
Because of company specific, I can not put the exact POM code but I can put what it looks like removing company specific stuff.
<dependency>
<groupId>com.group</groupId>
<artifactId>tools-app</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>com.group</groupId>
<artifactId>pom only dependency</artifactId>
<version>7.0</version>
<type>pom</type>
</dependency>
So tools app is the one that I am pulling it. It is the gradle build and uses the pom only dependency without any issue. If I pull this into a gradle app it works fine and builds. However, in the app that has this in the pom, if fails for above. So I add the dependency for the pom only dependency and mark it as type pom but still get the error.
So for my situation (and not the best solution), I went into the dependency that has only a pom and pulled the dependencies out of there and built. It worked. But feel there should be a way to make it work without having to do this.

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.

add external jar to our dependency

There is a jar file lets say "abc.jar" which maven dependency does not exist(ie created a jar by using java command of own classes). I want to add this jar as maven dependency so that at build time it will automatically copy that jar in lib folder as like other maven dependency. how i will do. please help .
Add it as a dependency with a system scope. See the docs here.
However, rather than adding it as a system dependency it might be better to mavenize the jar itself, then you can build and install it into your dependency management system.
Also, see this question: Can I add jars to maven 2 build classpath without installing them?
You can use the systemPath attribute in the dependency tag in the POM file of your project.
In your pom.xml, use the following snippet corresponding to abc.jar:
<dependencies>
<!-- Other dependencies -->
<dependency>
<groupId>abc</groupId>
<artifactId>x</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>{path_to_abc.jar}</systemPath>
</dependency>
</dependencies>
The scope parameter corresponding to this artifact must be set to system, for the artifact to be picked up from the specified systemPath.
Hope this helps!
A normal maven dependency is always resolved by looking into a repository. So you must put your JAR file into a repository.
You could install your JAR into your local repository. Have a look at the install plugin. The install-file goal is your friend.
If other developers also need this JAR (because they are working with the same project), they either need to install it locally too, or - better - you deploy the JAR to a remote repository. Have a look at the deploy plugin. Here the deploy-file goal is your friend. For deploying artifacts, you need a repository manager like Nexus or Artifactory.
However, a dependency could also have the system scope (look at the other answers).

Add a dependency in Maven

How do I take a jar file that I have and add it to the dependency system in maven 2? I will be the maintainer of this dependency and my code needs this jar in the class path so that it will compile.
You'll have to do this in two steps:
1. Give your JAR a groupId, artifactId and version and add it to your repository.
If you don't have an internal repository, and you're just trying to add your JAR to your local repository, you can install it as follows, using any arbitrary groupId/artifactIds:
mvn install:install-file -DgroupId=com.stackoverflow... -DartifactId=yourartifactid... -Dversion=1.0 -Dpackaging=jar -Dfile=/path/to/jarfile
You can also deploy it to your internal repository if you have one, and want to make this available to other developers in your organization. I just use my repository's web based interface to add artifacts, but you should be able to accomplish the same thing using mvn deploy:deploy-file ....
2. Update dependent projects to reference this JAR.
Then update the dependency in the pom.xml of the projects that use the JAR by adding the following to the element:
<dependencies>
...
<dependency>
<groupId>com.stackoverflow...</groupId>
<artifactId>artifactId...</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
You can also specify a dependency not in a maven repository. Could be usefull when no central maven repository for your team exist or if you have a CI server
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>commons-utils</artifactId>
<version>1.3</version>
<scope>system</scope>
<systemPath>${basedir}/lib/commons-utils.jar</systemPath>
</dependency>
Actually, on investigating this, I think all these answers are incorrect. Your question is misleading because of our level of understanding of maven. And I say our because I'm just getting introduced to maven.
In Eclipse, when you want to add a jar file to your project, normally you download the jar manually and then drop it into the lib directory. With maven, you don't do it this way. Here's what you do:
Go to mvnrepository
Search for the library you want to add
Copy the dependency statement into your pom.xml
rebuild via mvn
Now, maven will connect and download the jar along with the list of dependencies, and automatically resolve any additional dependencies that jar may have had. So if the jar also needed commons-logging, that will be downloaded as well.
I'd do this:
add the dependency as you like in your pom:
<dependency>
<groupId>com.stackoverflow...</groupId>
<artifactId>artifactId...</artifactId>
<version>1.0</version>
</dependency>
run mvn install it will try to download the jar and fail. On the process, it
will give you the complete command of installing the jar with the error message. Copy that command and run it! easy huh?!
I'll assume that you're asking how to push a dependency out to a "well-known repository," and not simply asking how to update your POM.
If yes, then this is what you want to read.
And for anyone looking to set up an internal repository server, look here (half of the problem with using Maven 2 is finding the docs)

Categories