Find which dependency jar has required class - java

How can you find which dependency to import if you just know the class name.
Imagine i am getting error
hbase/mapreduce/HbaseDBMapper.java:[9,53] package org.apache.hadoop.hbase.mapreduce.replication does not exist
This is due to fact that i dont have dependency which can give me this package.
How can i find which dependency to import from maven repository or any other website

In general, http://www.findjar.com/ can be used to find the jar files and consequent maven dependencies, given a class.
In this specific case, you may want
<artifactId>hbase-server</artifactId>
<groupId>org.apache.hbase</groupId>
as the class is defined in https://github.com/apache/hbase/tree/master/hbase-server/src/main/java/org/apache/hadoop/hbase/mapreduce

Related

How to determine where a dependency is used? (Java, Maven)

When using Maven with Java, is it possible to see where a dependency is used? Specifically to know which classes in your project import a class from a given dependency?
This is especially difficult when the package naming of the class and the dependency declaration's tags do not line up.
For example, given a POM which contains a dependency:
<dependency>
<groupId>org.company.project</groupId>
<artifactId>someartifact</artifactId>
<version>1.0</version>
</dependency>
find all classes that uses it (such as):
import org.company.similarprojectnamebutnotquitethesame.packagecontinued.SomeClass
TLDR: Is there an efficient way to locate all files in my project that use a given dependency?
Use a JAR search engine that matches the class name with a package, such as findjar.com or help4j.com

Replace provided Maven dependency with local class

If I check my effective pom I will find the following entry:
<dependency>
<groupId>com.package.of.other.department</groupId>
<artifactId>someArtifact</artifactId>
<version>2.4.2</version>
<scope>provided</scope>
</dependency>
This comes from the parent pom that we have to use to let our software (bpmn processes) run on a company wide platform.
Now comes a hacky part. There will be a bigger change and we cannot use someArtifact anymore. Unfortunately that artifact gets called directly by all our processes (you design the process and configure the full qualified class name for an item) and can't just configure a different artifact, as that would most likely break a lot of the running processes.
The simple plan was to create a class with the same package name and with the same class name, remove every dependency to the original package and everything should work fine. During the tests I noticed that it doesn't use my new class but still the original one, most likely because it gets provided as dependency via the mandatory parent pom and for some reason prefers that over my local one.
Excluding a provided dependency from the parent pom doesn't seem to work that easily?! Any idea how I could solve my issue?
If the application is regular java, the class that will be load is the first class met in the classpath order.
If you use other runtime package dependency management, the strategy is different. As example you can adjust your import-package in OSGi to ensure the use a class contains in private-package.

About exist two same name class in different jar?

In my current project I used Guava Cache to cache something with expiration, but when actually call this interface, it had below error
Caused by: java.lang.NoSuchMethodError: com.google.common.base.Platform.systemNanoTime()J
at com.google.common.base.Ticker$1.read(Ticker.java:64)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2225)
And the reason is that there are two Platform in the classpath
one in Gauva, one in google-collections:jar
And LocalCache of Guava uses Paltform of google-collections causes this error. I have some question about this, why not Class in the same jar has higher priority? why not randomly choose one, but always use Platform of google-collections?
Yes it is possible that two jars include the same class name. It happens when you import for example two jars of different versions of the same library.
If you import dependencies using maven for example when you import a library it can import dependencies of other libraries causing this kind of problem. In this case you need to explicit that when you import a library you need to exclude a secondary dependency. This is done with the exclusions tag.
You can force priority by specifying classpath order. Java look for class in jars in order that is pecifyed in classpath.
In case you using maven and ide to run you have no control over order of classpath, but you can exclude dependee module from classpath.
<dependency>
<groupId>some</groupId>
<artifactId>id1</artifactId>
<version>1.0.0.0</version>
<exclusions>
<exclusion>
<groupId>another</groupId>
<artifactId>id2</artifactId>
</exclusion>
</exclusions>
</dependency>
In this case id2 will not be in your classpath anymore.
class loading priority will depends on the ClassLoader, you can find lot of articles about java class loading. if you are trying to run a standalone java application probably class loading will be done by URLClassLoader.
in this case all urls(jar file locations or classes) given in the -cp or -classpath will be added as URLs to the URLClassLoader, then when application needs to load a class this URLClassLoader will iterate through its URLs and once it found the class it will be loaded.
so everything depends on the class path order.
NOTE: but in some context class loading is not simple as this. ex: jboss-module class loader.

Maven dependency doesn't exist after pom.xml dependency addition in Java?

After I added this dependency to my pom.xml file:
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>5.0</version>
</dependency>
I tried to import com.miglayout.*; but I got the error:
package com.miglayout does not exist
How come nothing is wrong with other libraries I have imported using Maven in the same project, but I get issues with com.miglayout?
I believe the correct package is net.miginfocom.*
The maven groupId does not always correlate with the package name.
See MigLayout Javadocs
The classes inside the MiG layout library are under the packages:
net.miginfocom.swing for the miglayout-swing artefact
net.miginfocom.layout for the miglayout-core artefact (transitive dependency of miglayout-swing).
If you are using an IDE, you should not write the imports yourself and let the IDE handle it. This way, you will avoid mistakes relating to wrong package imports. Also, you should not use import on-demand and prefer single type import.

How do I determine which version of a class my object is?

I'm trying to write a plugin into a framework application (Joget). My plugin source looks something like this:
public class MyPlugin extends ExtDefaultPlugin implements ApplicationPlugin, ParticipantPlugin {
...
public void execute(){
...
SecurityContextImpl secContext = (SecurityContextImpl) WorkflowUtil.getHttpServletRequest().getSession().getAttribute("SPRING_SECURITY_CONTEXT");
}
}
When I run the plugin, I get the following exception.
java.lang.ClassCastException: org.springframework.security.context.SecurityContextImpl cannot be cast to org.springframework.security.context.SecurityContextImpl
I'm using Maven. Now since both have the same package name, I'm assuming I'm accidentally using the wrong package version in my plugin JAR (that contains the SecurityContextImpl class) than the one in the framework. But I've double-checked and it looks like I'm including the correct one in my plugin package.
Is there a way to see the classloader or source JAR of my class (e.g. using reflection in some manner)? Any other ideas on how to address this?
This type of java.lang.ClassCastException, where both classes names are equals, occur when the same class, or two class with the same name are loaded by 2 different classloaders.
I don't know Joget, but you are talking about plugin. Frameworks often load plugins in separate classloaders to ensure a proper isolation between them.
Since you say I've double-checked and it looks like I'm including the correct one in my plugin package., you may want to remove spring-security from your package, as it's probably already loaded by the framework classloader.
You're using Maven, so you may simply add <scope>provided</scope> to the spring-security dependency (but not sure, since we don't have your pom.xml)
I've got the same exception when I was running my plugin.
There are two cases in general:
1. The class is a local class.
And that is to say, there is no repository(groupId, artificateId, etc) to be deployed in the pom.xml of your plugin. The solution is, go the target folder and open the xxx-0.0.1-snapshot.jar file, then open META-INF/MANIFEST.MF, add the source file of that class /dependency/file.jar, then add the source jar to the dependency folder
Remarks: It is better to give a version of the your local file and add it as shown in your pom.xml to let it be found as src in your code.
<!-- your source jar need to be renamed as example-1.0.0.jar -->
<dependency>
<groupId>this.should.be.the.prefix.of.your.package</groupID>
<artificateId>file.name<artificateId>
<version>1.0.0</version>
<systemPath>${basedir}/lib/stclient_updated-1.0.0.jar</systemPath>
<scope>system</scope>
</dependency>
2. The class is a remote class with repository
I had this type of problem once because the repository is not correct, see also Maven Repository to find the official repository of the source.
I hope that it could help =)
Cheers

Categories

Resources