Issue creating and using a custom jar file - java

I have prepared some util classes.
I planned to make them as jar and distribute it to required projects.
My util classes uses some already existing custom code provided in the form of jar file.
My code is dependent on "MainUtil.jar" whi internally dependends on Java Servlet, Commons IO, Commons Codec and so on.....
My POM dependency looks as below.
<dependency>
<groupId>com.solutions</groupId>
<artifactId>sol-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
When I package my jar it looks fine.
But when my jar is used in a project where these my util classes are used , I could see a wierd issue.
The commonc-codec jar files are not included in the project package when packaged.
Also code which requies this common-codec is failing.
When I explicitly include the commons-codec dependency, everything works perectly.
My confusion is, why should I explicitly add the codec dependency when I should be resolved by Maven based on the POM of the custom jar files.
And why the issue is happening only with the commons-codec but not with other dependency.

Your code depends on all the other jars. When you create jar for your project the jar file does not contain all the dependent jar classes.
Where ever you are using your jar you have to use other dependent jars. You have not mentioned whether you are using maven there also. If yes then if you have defined dependency then all the dependent jars will be in the classpath.

Issue with you dependency resolving is,
the existing dependency in your project might have some dependency management on this jar. That is the reason, old jar is taking precedence over your custom jar dependency.
Thry adding exclusion in your already existing jar for this common-codec jar.
like
<dependency>
<... Your existing dependency ..>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>
Use this command and check how your dependency is being resolved.
mvn dependency:resolve
Then everything should be fine.

Related

AEM, Maven : duplicated package name

I want to add "fop-core" dependency.
My project was added "uber-jar" dependency already.
The uber-jar dependency has org.apache.fop.apps.FopFactory.java file.
But, doesn't have org.apache.fop.apps.FopFactoryBuilder.java file.
The fop-core dependency has both FopFactory.java and FopFactoryBuilder.java files.
Thus, my program loads FopFactory.java in "uber-jar" instead of "fop-core".
How can I resolve this duplication??
Can I remove "FopFactory.java" file in "uber-jar" dependency?
OR
Can I force load "FopFactory.java" file in "fop-core" dependency?
uber-jar
<groupId>com.adobe.aem</groupId>
<artifactId>uber-jar</artifactId>
<classifier>apis</classifier>
</dependency>
fop-core
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop-core</artifactId>
<version>2.5</version>
</dependency>
Make sure that the fop-core dependency is coming first in your pom. That should do the trick.
HTH, OliG
Echoing Oliver Gebert response, I did that a few months ago for Apache POI, in the main pom.xml, I put it as the first dependency:
<dependencyManagement>
<dependencies>
<!-- Apache POI (First in order to avoid conflict with the version from the UberJar) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>

Dependency of Type "POM"

I am trying to get an ESB system running using ServiceMix and ActiveMQ. But even before I get that far, I had a question about dependency types of POM. I got the maven dependency as:
<!-- https://mvnrepository.com/artifact/org.apache.servicemix/servicemix -->
<dependency>
<groupId>org.apache.servicemix</groupId>
<artifactId>servicemix</artifactId>
<version>7.0.1</version>
<type>pom</type>
</dependency>
Now when I run "clean install" on the the project in which I included this dependency, I don't see any of the activeMQ jars being copied in the classpath or available for compilation (I have copy-dependency written, so I can see what jar files are included). In this case, do I still have to explicitly mention the activeMQ dependency in my pom file? Like:
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-core -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
</dependency>
Any guidance would be appreciated. This ServiceMix is frustrating with the lack of documentation.
If you put a dependency of type pom into your <dependencies>, Maven will use the content of the POM as transitive dependencies. So everything in that POM will become a part of the classpath unless it has something like test scope or its version is overridden by some other part of the POM.
Putting a POM into the <dependencyManagement> is a different thing. Note that scope import is only for <dependencyManagement>.

Maven war plugin: Is all dependencies specified in pom get added to war?

I use maven-war-plugin in my pom to build my Vaadin application. My question is, if I added an unnecessary dependency (dependent library is not actually used in code) to my pom, Will maven-war-plugin still bundle the dependency into the war file it generates?
The answer to your question depends on the scope you specify in the <dependency> tag. Consider the following dependency tag:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>provided</scope>
</dependency>
The provided scope tells Maven to use the log4j JAR when compiling but to exclude it from the build, so it would not appear in your WAR. If, on the other hand, you used a scope of compile or runtime, then it would appear in the WAR.
If you don't specify any <scope>, then the default is compile, which means that the depedency will appear in the build output.

What is the difference between the GeoIP2 MaxMind pom and my local one?

I'm following this guide:
https://github.com/maxmind/GeoIP2-java
It says:
We recommend installing this package with Maven. To do this, add the dependency to your pom.xml:
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>2.2.0</version>
</dependency>
There is also pom.xml file in the Git repository of GeoIP2 which is much longer - what is the difference between them?
Cited from the official homepage:
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.
Think of the pom.xml as the heart of Maven. In the file you can specify dependencies (most typically jar files), and other information, such as how the project should be built. Without digging to deep into this, one of Maven's strengths is that it manages the dependencies of projects.
To answer your concrete question, GeoIP2 manages its dependencies using Maven. This section of its pom.xml defines them:
<dependencies>
<dependency>
<groupId>com.maxmind.db</groupId>
<artifactId>maxmind-db</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.20.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
</dependencies>
By using Maven in your own project, you will only need to add the one dependency to GeoIP2. Maven will then search for the dependency in a repository, typically the Maven Central Repository if Maven isn't configured to use another. It will also automatically download all other needed dependencies (transitive dependencies), in this case it would be the dependencies listed above, plus any other dependencies those in turn depend on, and so on.
So, a short recap: Without a dependency management tool like Maven, you would need to manually make sure you have all the correct dependencies on the classpath. Maven fixes this for you.

Retrieve Jetty from Maven Central Repository as project dependency in IntelliJ IDEA Project

I want to use Jetty as an embedded library in a Java project I'm working on in IntelliJ IDEA. However, there are many different packages for Jetty available from the Maven Central Repository. The JAR available for direct download from here is named as jetty-distribution-9.0.3.v20130506.tar.gz, so I assumed the best complete package available from the Maven Central Repo was org.eclipse.jetty:jetty-distribution:9.0.3.v20130506. But IntelliJ returns this error when attempting to use that coordinate to retrieve the library:
No files were downloaded for org.eclipse.jetty:jetty-distribution:9.0.3.v20130506
Why can't that package be found? And if it's not usable, which packages should I download?
Edit: I now realise that the coordinate I should have been using is org.eclipse.jetty.aggregate:jetty-all:9.0.3.v20130506. I can locate this at search.maven.org, but IntelliJ cannot find anything newer than version 7. Can anyone reproduce or explain this issue? Moved to new question.
Check the dependency type.
There are so called pom type of dependencies, which act as a list of other dependencies. To be able to fetch them, you have to mark them as pom dependencies in your pom.xml
If you only need the server component, try searching for this string
'org.eclipse.jetty:jetty-server:9.0.3.v20130506'
Maven dependencies have a type, which by default is jar. The jetty distribution package is not a jar, and as you can see in the central repository, you can download either a .zip or a .tar.gz, so you'll have to declare the dependency as:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-distribution</artifactId>
<version>${jetty.version}</version>
<type>zip</type>
</dependency>
If you build now, it will download the zip and the build will probably succeed. But, a zip is different from a jar, so depending on what you're actually doing in that build, you will have to do more things to actually make use of that zip.
You probably don't want to use the distribution package unless you're also building a standalone distribution (.zip) for your project as well, in which case you should probably use the maven-assembly-plugin which can unzip the jetty distribution and rezip your whole project.
What you should do is decide what exactly you're going to need and build a custom jetty. Here's the starting point, enough to be able to deploy a simple servlet-based application:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-xml</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-deploy</artifactId>
<version>${jetty.version}</version>
</dependency>
You're probably going to need this one as well, since this is how you can start Jetty:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-start</artifactId>
<version>${jetty.version}</version>
</dependency>
Look at the list of modules to see what else you might need, for example jetty-ajp, jetty-websocket, or jetty-jsp.

Categories