Skip to content

NameError: (NameError) uninitialized constant Gem::Package from version 9.3.0.0 #8434

@Shahafgo

Description

@Shahafgo

Hi all,

Currently we use Jruby version: 9.2.20.0 and we would like to upgrade to the latest version (9.4.9.0) but I started to notice this problem from 9.3.0.0.

We have a code that initialize the scriptingContainer like with ruby script:

private static final String GEMS_HELPER = "gems_helper.rb";

public synchronized void init() {
      if (scriptingContainer == null) {
          LocalContextScope localContextScope = resolveLocalContextScope();
          ScriptingContainer scriptingContainerInstance = new ScriptingContainer(localContextScope,
                  LocalVariableBehavior.PERSISTENT);
          scriptingContainerInstance.setClassLoader(Thread.currentThread().getContextClassLoader());
          IRubyObject gemsHelperClass;
          try (InputStream is = scriptingContainerInstance.getClassLoader().getResourceAsStream(GEMS_HELPER)) {
              EmbedEvalUnit result = scriptingContainerInstance.parse(is, GEMS_HELPER);
              gemsHelperClass = result.run();
          } catch (Exception e) {
              throw new IllegalStateException("Could not initialize gems helper", e);
          }

          this.gemsHelper = scriptingContainerInstance.callMethod(gemsHelperClass, "new", Object.class);
          this.scriptingContainer = scriptingContainerInstance;
          log.info("Initialized {} successfully", getClass().getSimpleName());
      }
  }

Ruby script gems_helper.rb:

require 'rubygems'
require 'rubygems/package'

 def name_version_platform(gem_file_path)
      spec = Gem::Package.new(gem_file_path).spec
      spec.name + ',' + spec.version.to_s + ',' + (spec.platform.nil? ? 'unknown' : spec.platform.to_s)
end

From my java code I am trying to call to name_version_platform function

 public NameVersionPlatformTuple getGemNameVersionPlatform(File gemFile) {
        String result = call("name_version_platform", gemFile.getAbsolutePath());
        String[] nvp = result.split(",");
        return new NameVersionPlatformTuple(nvp[0], nvp[1], nvp[2]);
    }

private <T> T call(String method, Object... params) {
            //noinspection unchecked
            return (T) getScriptingContainer().callMethod(gemsHelper, method, params);
    }

When I call name_version_platform from multiple thread in parallel I am getting the following error:

Caused by: org.jruby.exceptions.NameError: (NameError) uninitialized constant Gem::Package
at org.jruby.RubyModule.const_missing(org/jruby/RubyModule.java:4336)
at RUBY.name_version_platform(gems_helper.rb:30)

I have tried to debug the jruby library and I have noticed that the constant map in Jruby in some thread is partially full and does not contain the constant for Gem::Package

In addition I am adding couple of links to problems that seem related to it:

#6139
https://bugs.ruby-lang.org/issues/921

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions