i am using Maven 3 and trying to build a jar.Now there is a class which is present in two different dependent jars. Though the methods in the interface is different but maven is trying to get the method defined in the class in different jar . So how to ensure that the class is picked from another jar?
E.g the required class is xyz.class and is present in two differnet jars as:
jar1: com/mycompany/xyz.class
and jar2: com/mycompany/xyz.class
The xyz.class in jar1 is what maven is picking up i suppose but i want the one in jar2
Thanks
This is more of a Java compilation problem than Maven. Check out the answers for:
how to load same class from different jars
You'll need to define your custom class loader for this kind of situation.
Related
I want to use a class and in my pom there are two dependencies that support it: dependency1 and dependency2.
Using the class with dependency1 crashed my program, so I deleted it completely from pom and left dependency2 as it was and the code was working.
How do I tell maven to build my class with dependency2 and not dependency1, without deleting dependency1 (in case dependency1 contains something that I want to use in my code later on)?
You cannot sensibly use two libraries that contain classes with the same qualified class names.
So
either restrict yourself to one of them.
or use the Maven shade plugin to relocate the packages of one of the dependencies.
when you are importing the dependency in your respective class just check for the entire address of the dependency (the whole package structure) and make sure that you are using the dependency from the dependency2.
Also, if you have removed dependency1 from the pom.xml, maven will not put the dependency1 in the target folder which will be generated while building the project.
It's very unlikely to have the same class with same package name on two different dependencies.Because artifactIds are unique for each dependency even it belongs to the same groupdId. So if you solved your issue by using the dependency2's class then that's the class you need. And as you asked if you need dependency1 for any other task keeping the dependency1 on your pom.xml won't be a problem.Only thing that you need to take care is importing the class that you need exactly from dependency2.So please check your import statements in the class and see if it's importing the class from dependency2.
i have a maven project that has two dependencies: DependencyA and DependencyB. In each of the dependencies there is a class, lets call it FooClass.
Now there is a problem, because one class of my project needs the FooClass of DependencyA and another class needs the FooClass of DependencyB. But both classes load the FooClass of DependencyA.
Can i solve this problem with maven? Or do i have to think about the design of my project structure?
You should avoid getting two classes with same name in same package. This would lead to the idea that you have two modules of different versions of one code...
It would not be an issue if you had for instance com.yourcompany.yourproyectA.FooClass and com.yourcompany.yourproyectB.FooClass.
This scenario happens often and I have never had an issue with maven.
Regards
If two libraries need two different versions of the same library, I recommend to use a module system such as OSGi.
I am working on a web project that has 2 different dependencies being pulled into war file of the same class
(different versions, different package)
One is :
com.google.common.collect, and the other is Guava API package. When I run this service on websphere application server, it throws NoSuchMethodFound Exception at ImmutableList.copyOf. It clearly is loading the earlier class instead of the class from Guava which has the required functions.
I cannot change any dependency, how ever is it possible for me to override a particular dependency by other using maven?
How should I solve this problem?
If you have control over the WebSphere installation, you can also try this:
locate the jre lib directory of your application server (/WebSphere/AppServer/java/jre/lib)
create a directory 'endorsed' put your required jars into this directory( Guava API).
The jars in this directory will be loaded first and override what you have in you war file.
This is not recommended but you can use it as patch to override the conflicting classes.
The first matched class found on the classpath is used. Therefore if you can specify the classpath in different ways to try and influence what class is picked up. (i.e. specify the class that you want loaded first in the classpath). This is not a good practice because the Java specification does not guarntee to use the classpath order.
A better solution would be to manage the classloading yourself in the code. This can be done by
`ClassLoader myClassLoader = new MyClassLoader(libPath);
Object1 obj1 = myClassLoader .loadClass("com.google.common.collect", true);'
Now if a classloader attempts to load classes from a library, the dependent classes would be loaded by the same classloader that does not have access to the other libraries and dependencies.
Note: That if you use this and want to move to OSGi in the future you will incure some pain having to remove this code. Therefore try to limit it's use or switch to OSGi early!
I got this inherited project using Maven/m2e as the build automation tool. All nice & cool except that this project, checked out of SVN as is, is broken... meaning it fails to build, with several duplicate class errors:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.1:compile (default-compile) on project myproj: Compilation failure: Compilation failure:
[ERROR] \Users\Daniel\workspace\myproj\target\generated-sources\cxf\org\package1\services\ClassA.java:[36,7] duplicate class: org.package1.services.ClassA
Now, it's true that ClassA exists in the build environment 3 times:
c:/Users/Daniel/workspace/myproj/src/main/java/org/package1/services/ClassA.java
c:/Users/Daniel/workspace/myproj/src/main/java/org/package1/www/services/ClassA.java
c:/Users/Daniel/workspace/myproj/target/generated-sources/cxf/org/package1/services/ClassA.java
But they belong to different packages:
package org.package1.services;
package org.package1.www.services;
So, why would the compiler complain about a duplicate class?
(Or is it Maven that's complaining?)
I am not familiar with the design considerations of the original author, so any idea how to resolve these duplicates would be much appreciated.
You've got three classes, in two packages. Therefore two of the classes are in the same package. These two files:
.../myproj/src/main/java/org/package1/services/ClassA.java
.../myproj/target/generated-sources/cxf/org/package1/services/ClassA.java
... are both contributing org.package1.services.ClassA (which is the fully-qualified class name the compiler is complaining about, note). It's not clear which one you should be using, based on the information you've given.
The fact that the class has the same simple name in different packages does not matter; a class is considered by it's full named which also contains the package name. In Java you can actually have two classes by the same full name in the same JVM as long as they are loaded by two different class loaders (this is not your case).
Now you have two classes that have the same name org.package1.services.ClassA one written by you and one generated; if you need them both and you do not want them renamed you need to use a different classloader for one of them (kind of complicated so it would be simple if you renamed your generated class).
It is not ClassA which is duplicated but org.package1.services.ClassA which is duplicated.
You need to change that the package eorg.package1.services; doesn't appear at the start of the other files.
I'm trying IntelliJ IDEA after many years as an Eclipse user. At the same time, I'm working on a project that I've inherited with many dependencies.
One class will not compile, because IDEA claims that a method in another class does not exist. I can see the method in its source. Control-clicking on the class name in the IDEA editor takes me to the source that looks OK.
My hypothesis is that the compiler isn't using the class compiled from the source within the project, but a class with the same name, somewhere among my dozens of library jars.
How can I find out where IDEA's compiler is finding the clashing class?
CTRL-N and entering the class name should show you all of the matching classes from across the classpath, and which directory/JAR they're in. If there's a clash, you should have duplicates in that list.
Another possibility is that the source you have for the referenced class doesn't match the compiled version of that class.