Define packages for classes in nested JARs#3160
Conversation
|
very interesting, I did not know overriding class-loader might need to call UPDATE: actually for jruby-1_7 the path is only test (those tests were moved under test/jruby on master) ... |
|
+1 to get this in with a test |
|
Great, thanks for the feedback. I tried to get the test suit running properly this morning, which ended in |
cd3dbc7 to
c0a9e8e
Compare
Packages are defined in the private `defineClass(String name, Resource res)` of `URLClassLoader`, which is only called from `findClass(final String name)`. Thus, whenever `findClass()` in `URLClassLoader` throws `ClassNotFoundException` (e.g. for JARs within JARs), the package doesn't get defined, even if `findClass(String className)` in `JRubyClassLoader` is able to find and define the sought class. I've used http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/net/URLClassLoader.java for reference.
The example would fail unless the package has been defined, as JavaClass#package would return nil, which obviously doesn't define the method #name.
|
I've finally managed to get (at least some of) the tests working and have added a test for defining packages for classes in nested JARs. As for using the JARs manifest for
|
Define packages for classes in nested JARs
|
@jowl excellent, thanks ... maybe for your notes on what might be done further, please open a new issue |
|
@kares I hope you know this is not required for jruby-9k. we improved the current situation already quite a bit with his patch. not sure we should invest further until there is real need, i.e. blocking people to use jruby-1.7.x just my thoughts on this. |
|
@mkristian yeah, thanks - just figured as I'm once again struggling through the merge :( |
|
@kares sorry about not being clear about this not being required in 9k in the description and not noticing the JRuby 9000 label. Given @mkristian's input, I won't pursue this any further now. Thanks guys. |
JRubyClassLoaderdoesn't define packages for classes found in JARs in JARs in JRuby 1.7 (it works as expected on master). The following example demonstrates the behavior:mkdir -p src/{main,nested} bin build echo "package main; class Main { }" > src/main/Main.java echo "package nested; class Nested { }" > src/nested/Nested.java javac -sourcepath src -d bin src/*/*.java jar cf build/main.jar -C bin main jar cf build/nested.jar -C bin nested jar uf build/main.jar -C build nested.jar ruby -rbuild/main -rnested -e'[Java::Main::Main, Java::Nested::Nested].each { |c| printf("%s.java_class.package # => %s\n", c.name, c.java_class.package) }'In the example, a JAR containing the class
main.Mainand another JAR containing the classnested.Nestedcreated. The Ruby script then loads these classes and prints out the package names; which ismainformain.Main, but empty fornested.Nested.Packages are defined in the private
defineClass(String name, Resource res)ofURLClassLoader, which is only called fromfindClass(final String name). Thus, wheneverfindClass()inURLClassLoaderthrowsClassNotFoundException(e.g. for JARs within JARs), the package doesn't get defined, even iffindClass(String className)inJRubyClassLoaderis able to find and define the sought class. I've used http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/net/URLClassLoader.java for reference.This proposed solution is a simplified version of that in the
URLClassLoaderin that it doesn't care about versioning information and sealing. The reason for this is that I really don't know anything about it andURLClassLoaderdefaults to defining packages in the same manner whenever a manifest isn't available.I didn't know whether to include the example above as an integration test example or not? If I would, I thought I'd add the JAR as a fixture and then simply assert on the package name. I'd really appreciate feedback on my code, as well as on the PR description, so that I can improve.