Java类路径不同的顺序会导致“找不到方法错误”吗?

huangapple go评论172阅读模式
英文:

Does Java classpath different order give "No Method found error"

问题

我有一个Scala Akka应用程序,它连接到部署在Rancher上的HBase(目前是CDP,之前是HDP);在连接到HDP HBase时从未遇到任何问题;自从从HDP切换到CDP之后,使用相同的镜像,我们在一个容器的一个依赖类中获得了找不到方法的错误,而另一个相同镜像的容器可以正常连接到HBase。尽管该JAR文件存在于相同的镜像和类路径中。

一个明显的区别是类路径的顺序发生了变化。

  1. 类路径顺序的更改会影响JAR文件的可用性吗?
  2. 当Java库/类在启动时经历更快的CPU周期时,它们的加载顺序会有所不同吗?

出现“找不到类方法”的原因是什么?

英文:

I have a Scala Akka Application which connects to HBase (currently CDP earlier HDP) deployed on rancher; Never faced any trouble when connecting to HDP hbase; Since recent HDP to CDP change, with the same image we are getting no method found on one of the dependency's class in one of the container, where as another container of same image connects to hbase properly.; even though the jar exists in the same image and classpath also.

one of the noticeable difference is change in the order of classpath.

  1. Does change in the classpath order will effect the jars availability.
  2. Does java libraries/classes would load in different order when they would hit a faster CPU cycle at startup.

What could be the reason for such "no class method found".

答案1

得分: 1

可以肯定地说,如果相同的类文件存在于不同的类路径条目中,是可能会出现问题的。例如,如果你的类路径是:java -cp a.jar:b.jar com.foo.App,并且:

a.jar:

pkg/SomeClass.class
b.jar:

pkg/SomeClass.class

那么就有可能发生这种情况 - 通常是因为类路径中的一个 JAR 文件版本较旧,或者更复杂的情况:你的类路径中的一个 JAR 包含了许多不同的库,而其中一个组件的版本较旧。

以下是一些基本的注意事项:

  1. 不要将 JAR 文件混合在一起。如果你有 500 个依赖项,就在你的类路径上放置 500 个条目。我们有工具来管理这些内容,要使用它们。不要创建合并的 JAR 包、超级 JAR 包等等。
  2. 使用依赖项跟踪工具检查依赖链中是否存在版本差异。如果你的应用程序依赖于“hibernate”和“jersey”,它们都依赖于谷歌的 guava 库,但 hibernate 导入的是 v26,jersey 导入的是 v29,那就会有问题。要意识到这一点,并确保你明确决定了最终采用哪个版本。你可能会希望明确选择 v29,并可能检查 hibernate 是否也能运行在 v29 上。如果不能,那就有更大的问题。虽然这些问题是可以解决的(使用模块化类加载器),但并不容易。

例如,如果你使用 Maven,可以看看 enforcer 插件(groupId: org.apache.maven.plugins,artifactId: maven-enforcer-plugin)。

英文:

It certainly can, if the same class file is present in different classpath entries. For example, if your classpath is: java -cp a.jar:b.jar com.foo.App, and:

a.jar:

pkg/SomeClass.class
b.jar:

pkg/SomeClass.class

Then this can happen - usually because one of the jars on your classpath is an older version than the other, or the same but more complicated: one of the jars of your classpath contains a whole heap of different libraries all squished together and one of those components is an older version.

There are some basic hygiene rules to observe:

  1. Don't squish jars together. If you have 500 deps, put 500 entries on your classpath. We have tools to manage this stuff, use them. Don't make striped jars, uber jars, etc.
  2. Use dependency trackers to check if there are version difference in your dependency chain. If your app depends on, say, 'hibernate' and 'jersey', and they both depend on google's guava libraries, but hibernate imports v26 and jersey imports v29, that's problematic. Be aware of it and ensure that you explicitly decide which version ends up making it. Presumably, you'd want to explicitly pick v29 and perhaps check that hibernate also runs on v29*. If it doesn't, you have bigger problems. They are fixable (with modular classloaders), but not easily.

*) Neither hibernate nor jersey actually depend on guava, I'm just using them as hypothetical examples.

For example, if you use maven, check out the enforcer plugin. (groupId: org.apache.maven.plugins, artifactId: maven-enforcer-plugin).

答案2

得分: 0

我赌的是在 CDP 的某处有这个 jar 的另一个版本,而且有时它会在你的项目所提供的版本之前被加载,从而导致了错误。

因此,当你的容器启动时,尝试记录出现冲突的类是从哪个位置加载的。这个问题可能会对你有帮助:https://stackoverflow.com/questions/1983839/determine-which-jar-file-a-class-is-from

英文:

My bet is that there is another version of the jar somewhere in CDP, and occasionally it is loaded before the version that you ship with your project, causing the error.

So, when your container starts, try logging from which location the conflicting class is loaded. This question might help you: https://stackoverflow.com/questions/1983839/determine-which-jar-file-a-class-is-from

huangapple
  • 本文由 发表于 2020年10月10日 20:36:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/64293485.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定