You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确从Java调用JRuby中Test模块的Test_1方法?

Java调用Ruby模块方法报错的解决方法

问题场景

尝试从Java调用Ruby模块中的方法,运行后报错提示方法未定义,相关代码及错误信息如下:

Ruby代码文件

test_a.rb

module Test
    def Test.Test_1
        stmt = "Test 1"
        stmt
    end
end

test.rb(引入test_a.rb)

require_relative "./test/test_a.rb"

Java调用代码

package com.example;

import java.util.ArrayList;

import org.jruby.embed.LocalContextScope;
import org.jruby.embed.LocalVariableBehavior;
import org.jruby.embed.PathType;
import org.jruby.embed.ScriptingContainer;

public class test_ruby {
    public static void main(String[] args) {
        try {
            ScriptingContainer jruby = new ScriptingContainer(LocalContextScope.THREADSAFE, LocalVariableBehavior.GLOBAL);
            ArrayList<String> loadPath = new ArrayList<>();
            loadPath.add("C:\\Users\\nikol\\Downloads\\starter\\ruby\\base");
            jruby.setLoadPaths(loadPath);
            System.out.println("Load Files");
            jruby.runScriptlet(PathType.RELATIVE, "ruby\\\\base\\test\\lib\\test.rb");
            String returnValue = jruby.runRubyMethod(String.class, null, "Test.Test_1");
            System.out.println(returnValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

错误信息

Load Files
org.jruby.embed.InvokeFailedException: org.jruby.exceptions.NoMethodError: (NoMethodError) undefined method `Test.Test_1' for nil:NilClass
        at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.doInvokeMethod(EmbedRubyObjectAdapterImpl.java:251)
        at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.runRubyMethod(EmbedRubyObjectAdapterImpl.java:198)
        at org.jruby.embed.ScriptingContainer.runRubyMethod(ScriptingContainer.java:1579)
        at com.example.test_ruby.main(test_ruby.java:19)
Caused by: org.jruby.exceptions.NoMethodError: (NoMethodError) undefined method `Test.Test_1' for nil:NilClass

正确调用方式

错误原因是runRubyMethod不能直接把Test.Test_1作为方法名传入,有两种可行的解决方式:

方式一:获取模块对象后调用方法

先获取Test模块的Ruby对象,再调用其对应的方法:

package com.example;

import java.util.ArrayList;

import org.jruby.embed.LocalContextScope;
import org.jruby.embed.LocalVariableBehavior;
import org.jruby.embed.PathType;
import org.jruby.embed.ScriptingContainer;

public class test_ruby {
    public static void main(String[] args) {
        try {
            ScriptingContainer jruby = new ScriptingContainer(LocalContextScope.THREADSAFE, LocalVariableBehavior.GLOBAL);
            ArrayList<String> loadPath = new ArrayList<>();
            loadPath.add("C:\\Users\\nikol\\Downloads\\starter\\ruby\\base");
            jruby.setLoadPaths(loadPath);
            System.out.println("Load Files");
            // 加载Ruby文件
            jruby.runScriptlet(PathType.RELATIVE, "ruby\\\\base\\test\\lib\\test.rb");
            // 获取Test模块对象
            Object testModule = jruby.runScriptlet("Test");
            // 调用模块中的Test_1方法
            String returnValue = jruby.runRubyMethod(String.class, testModule, "Test_1");
            System.out.println(returnValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方式二:直接执行Ruby调用语句

使用runScriptlet直接执行完整的Ruby方法调用语句,写法更简洁:

package com.example;

import java.util.ArrayList;

import org.jruby.embed.LocalContextScope;
import org.jruby.embed.LocalVariableBehavior;
import org.jruby.embed.PathType;
import org.jruby.embed.ScriptingContainer;

public class test_ruby {
    public static void main(String[] args) {
        try {
            ScriptingContainer jruby = new ScriptingContainer(LocalContextScope.THREADSAFE, LocalVariableBehavior.GLOBAL);
            ArrayList<String> loadPath = new ArrayList<>();
            loadPath.add("C:\\Users\\nikol\\Downloads\\starter\\ruby\\base");
            jruby.setLoadPaths(loadPath);
            System.out.println("Load Files");
            jruby.runScriptlet(PathType.RELATIVE, "ruby\\\\base\\test\\lib\\test.rb");
            // 直接执行Ruby方法调用
            String returnValue = (String) jruby.runScriptlet("Test.Test_1");
            System.out.println(returnValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

内容的提问来源于stack exchange,提问作者Nik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:58:16