Jruby& OSGi - 如何一起工作?

时间:2014-01-23 02:54:40

标签: osgi jruby

我想创建一个简单的osgi包来运行ruby源文件,所以我使用jruby-complete。这是代码示例

运行jruby文件的包

package activator;
import org.jruby.embed.ScriptingContainer;

public class Main {
    public void runRubySource(String[] args) {
        try {
            System.out.println("JRUBYYYYYYYYYYYYYYYYYYYYYYYYy");
            ScriptingContainer container = new ScriptingContainer();
            container.setArgv(args);
            container.runScriptlet("require 'ruby/test.rb'");
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }

    }
}

使用上述捆绑

的捆绑包
package activator;
import activator.Main;
import org.jruby.embed.ScriptingContainer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Test implements Activator{

    @Override
    public void start(BundleContext context) throws Exception {
        // TODO Auto-generated method stub
        Main m = new Main();
        String[] args = {"-c","C:\\fileconfig.conf"};
        m.runRubySource(args );

    }
    @Override
    public void stop(BundleContext context) throws Exception {
        // TODO Auto-generated method stub

    }
}

使用maven进行osgi包构建的POM文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.insight</groupId>
    <artifactId>jruby</artifactId>
    <packaging>bundle</packaging>
    <name>JrubyDemo</name>
    <version>1.0</version>
    <dependencies>
        <dependency>
            <groupId>org.jruby</groupId>
            <artifactId>jruby-complete</artifactId>
            <version>1.7.10</version>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>4.3.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.0.1</version>
                <extensions>true</extensions>
                <configuration>
                    <Embed-Transitive>true</Embed-Transitive>
                    <Export-Package>*</Export-Package>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

步骤:

当然,jruby / jruby.rb包含在jruby-complete.jar中,而不是我的示例包中

那么,我该怎么办?

2 个答案:

答案 0 :(得分:1)

  

(LoadError)没有要加载的文件--jruby / jruby.rb

我认为你的捆绑可能是腐败的。 BTW,jruby-complete已经是一个OSGI包,所以尝试相同而不包装:它应该能够加载自己的类。

然而,下一步:

  

container.runScriptlet(&#34;要求&#39; ruby​​ / test.rb&#39;&#34;);

您要求jruby包中的类从另一个包中加载资源。 问题是jruby-complete不知道你的捆绑包,因为它没有通过正常的OSGI机制连接到它。

所以你需要某种形式的反向查找机制,让Jruby包在其他包中找到资源/类,而不向Jruby的包添加直接依赖(RequireBundle或ImportPackage)(因为它不会如果您希望能够从其他包中加载,或者在其他上下文中重用jruby,则可以进行扩展。)

我正在使用Eclipse Equinox进行类似的设置,所以我已经被宠坏了#34;与Buddy Policy等令人讨厌的对待。除了特定于该容器有自己的disadvantages,但它对我来说已经足够了。

目前,一个通用的OSGI&#39;等同于&#39;对于BuddyPolicy =全球似乎是 DynamicImport-Package,但它仅作为最后的手段,因为它不如上述灵活。

以上两个都涉及在Jruby bundle的Manifest中添加一行(同样是jruby-complete.jar,但我碰巧将整个东西重新打包为org.jruby)。

更好的解决方案可能是JRuby自己的OSGiScriptingContainer,您可以将加载包传递到您的类中,如下所示:

package activator;
import org.jruby.embed.OSGIScriptingContainer;

public class Main {
    public void runRubySource(String[] args) {
        try {
            System.out.println("JRUBYYYYYYYYYYYYYYYYYYYYYYYYy");
            ScriptingContainer container = new OSGIScriptingContainer(Activator.getBundle());  // 
            container.setArgv(args);
            container.runScriptlet("require 'ruby/test.rb'");
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }    
    }
}

我还没有尝试过,但我会改变我的设置,因为这似乎是正确的方法。

答案 1 :(得分:0)

脚本通常在OSGI中略有不同,因为脚本可以是/是运行时,OSGI希望您在构建时指定内容(从链接的线程中提取)。对于使用JRuby的脚本编写,您最好使用JSR-223加载引擎,因为已经有工作使这两种稍微不兼容的技术一起工作。

这是一个类似的线程,讨论在OSGI中使用JSR-223和一些解决方案:

Is OSGi fundamentally incompatible with JSR-223 Scripting Language Discovery?