Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util)) #4861

Closed
javalovercn opened this issue Nov 21, 2017 · 7 comments

Comments

@javalovercn
Copy link

  1. new Eclipse Java project, and add a class named 'SecondUtil.java' in package 'com.util'
package com.util;

public class SecondUtil {
	public SecondUtil(){
		System.out.println("SecondUtil");
	}
}
  1. add a class named 'TestMain.java' in package 'com'
package com;

import org.jruby.embed.ScriptingContainer;

public class TestMain {
	public static void main(final String[] args) {
		final ScriptingContainer sc = new ScriptingContainer();
		sc.runScriptlet("Java::com.util.SecondUtil::new()");
	}
}
  1. import lib jruby-complete-9.1.14.0.jar
  2. run TestMain, console prints 'SecondUtil', all is OK.
  3. add a class 'Util.java' in package 'com' to current project
package com;

public class Util {
	public Util(){
		System.out.println("this is Util.");
	}
}
  1. run TestMain, console prints following error:
NameError: cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util))
  method_missing at org/jruby/javasupport/JavaPackage.java:259
          <main> at <script>:1
Exception in thread "main" org.jruby.embed.EvalFailedException: (NameError) cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util))
	at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:131)
	at org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1307)
	at org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1300)
	at com.TestMain.main(TestMain.java:8)
Caused by: org.jruby.exceptions.RaiseException: (NameError) cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util))
	at org.jruby.javasupport.JavaPackage.method_missing(org/jruby/javasupport/JavaPackage.java:259)
	at RUBY.<main>(<script>:1)
  1. change jruby-complete-9.1.14.0.jar to jruby-complete-1.7.3.jar
  2. run TestMain, it works well.
@headius
Copy link
Member

headius commented Nov 21, 2017

So we are having problems locating a class when there's a package of the same-but-lowercase name.

@kares You've done a lot of tweaking and optimizing of Java integration...perhaps some search order got reversed, or we're using the package name to try to load the class?

@headius
Copy link
Member

headius commented Nov 21, 2017

@javalovercn Is there a reason you closed this? I was able to reproduce locally, so I do believe this is a bug.

@headius
Copy link
Member

headius commented Nov 21, 2017

@kares The following fixes the problem for me and does not cause any regressions. Please review. Needs a test, obviously.

diff --git a/core/src/main/java/org/jruby/javasupport/Java.java b/core/src/main/java/org/jruby/javasupport/Java.java
index e481b7d113..73e8e7326b 100644
--- a/core/src/main/java/org/jruby/javasupport/Java.java
+++ b/core/src/main/java/org/jruby/javasupport/Java.java
@@ -961,13 +961,16 @@ public class Java implements Library {
             // cannot link Java class com.sample.FooBar needs Java 8 (java.lang.UnsupportedClassVersionError: com/sample/FooBar : Unsupported major.minor version 52.0)
             throw runtime.newNameError("cannot link Java class " + className + ' ' + msg, className, ex, false);
         }
+        catch (NoClassDefFoundError | ClassNotFoundException ncdfe) {
+            // let caller try other names
+            return null;
+        }
         catch (LinkageError ex) {
             throw runtime.newNameError("cannot link Java class " + className + ' ' + '(' + ex + ')', className, ex, false);
         }
         catch (SecurityException ex) {
             throw runtime.newSecurityError(ex.getLocalizedMessage());
         }
-        catch (ClassNotFoundException ex) { return null; }
 
         if ( initJavaClass ) {
             return getProxyClass(runtime, JavaClass.get(runtime, clazz));

@headius headius reopened this Nov 21, 2017
@headius
Copy link
Member

headius commented Nov 21, 2017

@kares I went ahead with it because everything JI-related looked ok.

I also figured out this was probably introduced when you cleaned up the RaiseException nonsense in getProxyClassOrNull in 77ef13e. Took over 2.5 years for someone to run into this case!

@kares
Copy link
Member

kares commented Nov 21, 2017

heh, time sure flies and bugs prevail. makes sense - thanks for the fix 💜

robbavey added a commit to elastic/logstash that referenced this issue May 19, 2022
This commit updates the version of jruby used in Logstash to `9.3.4.0`.

* Updates the references of `jruby` from `9.2.20.1` to `9.3.4.0`
* Updates references/locations of ruby from `2.5.0` to `2.6.0`
* Updates java imports including `org.logstash.util` to be quoted
  * Without quoting the name of the import, the following error is observed in tests:
  * `java.lang.NoClassDefFoundError: org/logstash/Util (wrong name: org/logstash/util)`
  * Maybe an instance of jruby/jruby#4861
* Adds a monkey patch to `require` to resolve compatibility issue between latest `jruby` and `polyglot` gem 
  * The addition of jruby/jruby#7145 to disallow circular
causes, will throw when `polyglot` is thrown into the mix, and stop logstash from
starting and building - any gems that use an exception to determine whether or not
to load the native gem, will trigger the code added in that commit.
  * This commit adds a monkey patch of `require` to rollback the circular cause exception
back to the original cause.
* Removes the use of the deprecated `JavaClass`
* Adds additional `require time` in `generate_build_metadata`
* Rewrites a test helper to avoid potentially calling `~>` on `FalseClass`


Co-authored-by: Joao Duarte <jsvduarte@gmail.com>
Co-authored-by: João Duarte <jsvd@users.noreply.github.com>
@izayaaaaaaa
Copy link

So we are having problems locating a class when there's a package of the same-but-lowercase name.

@kares You've done a lot of tweaking and optimizing of Java integration...perhaps some search order got reversed, or we're using the package name to try to load the class?

This also happens in a java project in vs code when the package name 'addIt' and the class name 'AddIt' are the same but with different character cases.

java.lang.NoClassDefFoundError: addIt/AddIt (wrong name: AddIt)

@kares
Copy link
Member

kares commented Nov 15, 2022

@izayaaaaaaa that sounds like a similar bug - might be worth opening a clean new issue as the cause seems to be different.
BONUS points if you have a clean reproducer with latest JRuby 9.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants