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

ScriptingContainer with LocalContextScope.THREADSAFE share JRubyClassLoader with all runtimes #2561

Closed
mkristian opened this issue Feb 4, 2015 · 8 comments

Comments

@mkristian
Copy link
Member

ScriptingContainer with LocalContextScope.THREADSAFE share one instance of JRubyClassLoader with all runtimes. since each runtime loads it own set of jar files but they get shared by the shared JRubyClassLoader. for example each runtime can load its own version of bouncycastle jars which will result one classloader having all those BC jars loaded.

the real world problem is when a lot of thread startup with require 'openssl' conditions can arise where some classes can not be loaded from the JRubyClassLoader: http://ruby.11.x6.nabble.com/JRuby-complete-multi-threading-and-java-lang-NoClassDefFoundError-td5004808.html

IMO each runtime should have its own JRubyClassloader to separate the set if required jars per runtime.

@joedaniels29
Copy link

does this issue imply that a java application server like glassfish cant run several different apps with several different versions of jruby/openssl/BC?

@mkristian
Copy link
Member Author

@joedaniels29 the above problem is when you have several jruby runtimes (or ScriptingContainers) inside one classloader. all those runtimes share a child classloader the JRubyClassloader. with this JRubyClassLoader requiring BC and all the other jars needs to be synchroinized.

having several webapps inside a servlet engine are nicely separated and can run different versions of jruby or BC, etc.

@mkristian
Copy link
Member Author

two possible implementations:

  • each runtime gets it own JRubyClassloader and with this each one has its own set of loaded jars
  • ensure one the same jar is loaded only once into the JRubyClassLoader which is not the case right now. with one runtime, the require does take care of it, but with several runtimes sharing the same JRubyClassLoader this needs extra work

@kares would appreciate your input here :)

@kares
Copy link
Member

kares commented Jan 5, 2016

@mkristian aah, get it now - thanks for the explanation. never realised the case but it makes sense.
hmm I would vote for the "easy" way 1. but I'm afraid to put it in 1.1.x stable. on the other hand sounds like this might be JRubyClassLoader's responsibility (or we could setup a custom class-loader in JRuby-Rack assuming we can change the JRubyClassLoader used in Ruby) - probably doable decently. let me know if you're not looking into it, I will (if I do not forget or someone ping-s me)

@mkristian
Copy link
Member Author

@kares for me 1) is the only clean solution - let me see what it needs and then we look at the "risk"

@mkristian
Copy link
Member Author

I looked into this and the following class can reproduce it with jruby-1_7

public class Hmm {


    public static void main(String... args) throws Exception {
        int num = 20;
        if (args.length > 0) {
            num = Integer.parseInt(args[0]);
        }
        Thread[] threads = new Thread[num];
        final ScriptingContainer runtime = new ScriptingContainer(LocalContextScope.THREADSAFE);
        for(int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Runnable() {
                public void run() {
                    System.err.println(runtime.parse("p JRuby.runtime.jruby_class_loader;require 'openssl';p $CLASSPATH").run());
                }
            });
        }
        for(Thread t: threads) {
            t.start();
        }
        for(Thread t: threads) {
            t.join();
        }
    }
}

I used jruby-complete.jar and this class one the classpath.

with jruby-9k I do not see the error.

apparently then I created the issue something was really obvious for me BUT I can not see anything why the JRubyClassLoaders are not separated :(

since jruby-9k does not see the original error I am inclined to "won't fix" it on jruby-1_7 and close the issue.

beside this I still think this issue is related to jruby/warbler#356

@kares
Copy link
Member

kares commented Jan 5, 2016

@mkristian thanks, as I quickly looked through jruby-rack I did not find how you'd like to proceed on 1)
... as the runtime has always its own JRubyClassLoader - feel the same - not worth looking (as its clearly not obvious) unless paid by the hour :)

@mkristian
Copy link
Member Author

it works on jruby-9k and as an etch-case I am closing it

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

3 participants