Skip to content

Since JRuby-9.0.0.0 changes to classloaders are failing ruby-processing #3152

@monkstone

Description

@monkstone

JRuby is losing the magic that let ruby-processing just work:-
To make ruby-processing work it is important that ruby and java classes can be added somewhat dynamically (including those with native binaries), the recent changes to the class loaders in JRuby-9.0.0.0 are making it all but impossible to combine say video libraries (incorporating gstreamer and the like) and graphics (OPENGL). In some ways this is a continuation the issue that I reported earlier #3036 which can be fixed for simple cases by loading the jars onto the java classpath. Now if there were a new way of doing this, but incompatible with the old way I would be very interested as I am trying to create a new version of ruby-processing JRubyArt. Here is what I currently have to do add video library to JRubyArt (this is hard coded in the app and OK for core libraries.

    def video
      Dir["#{Processing::RP_CONFIG['sketchbook_path']}/libraries/video/library/\*.jar"]
    end

previously with ruby-processing we were able to add the jars from ruby and in our library _loader used the following hack to load the native binaries (even when not in a jar)

    # HACK: For pure java libraries, such as the ones that are available
    # on this page: http://processing.org/reference/libraries/index.html
    # that include native code, we mess with the 'Java ClassLoader', so that
    # you don't have to futz with your PATH. But it's probably bad juju.
    def load_java_library(library_name)
      library_name = library_name.to_sym
      return true if @loaded_libraries.include?(library_name)
      jpath = get_library_directory_path(library_name, 'jar')
      jars = get_library_paths(library_name, 'jar')
      return false if jars.empty?
      jars.each { |jar| require jar }
      platform_specific_library_paths = get_platform_specific_library_paths(jpath)
      platform_specific_library_paths = platform_specific_library_paths.select do |ppath|
        FileTest.directory?(ppath) && !Dir.glob(File.join(ppath, '*.{so,dll,jnilib}')).empty?
      end
      unless platform_specific_library_paths.empty?
        platform_specific_library_paths << java.lang.System.getProperty('java.library.path')
        new_library_path = platform_specific_library_paths.join(java.io.File.pathSeparator)
        java.lang.System.setProperty('java.library.path', new_library_path)
        field = java.lang.Class.for_name('java.lang.ClassLoader').get_declared_field('sys_paths')
        if field
          field.accessible = true
          field.set(java.lang.Class.for_name('java.lang.System').get_class_loader, nil)
        end
      end
      @loaded_libraries[library_name] = true
    end

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions