【问题标题】:Jruby & OSGi - How to working together?Jruby & OSGi - 如何一起工作?
【发布时间】:2014-01-23 02:54:39
【问题描述】:

我想创建一个简单的 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 中,而不是在我的示例包中

那么,我该怎么办??

【问题讨论】:

    标签: osgi jruby


    【解决方案1】:

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

    我认为您的捆绑包可能已损坏。 顺便说一句,jruby-complete 已经是一个 OSGI 包,所以不包装也可以试试:它肯定能够加载自己的类。

    但是,对于下一步:

    container.runScriptlet("require 'ruby/test.rb'");

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

    因此,您需要某种形式的反向查找机制,让 Jruby 捆绑包在其他捆绑包中定位资源/类,而不向 Jruby 捆绑包添加直接依赖项(RequireBundle 或 ImportPackage)(因为如果您愿意,这将无法扩展然后能够从其他包中加载,或者可能在其他上下文中重用 jruby)。

    我正在使用 Eclipse Equinox 进行类似的设置,所以我被 Buddy Policy 这样的讨厌的东西“宠坏了”。除了特定于该容器之外,它还有自己的disadvantages,但对我来说已经足够了。

    目前 BuddyPolicy=Global 的一个通用 OSGI“等效”似乎是 DynamicImport-Package,但它只是作为最后的手段,不如上述灵活。

    以上两个都涉及在 Jruby 包的清单中添加一行(同样是 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());
            }    
        }
    }
    

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

    【讨论】:

    • 谢谢,OSGIScriptingContainer 解决了我的问题 :)
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-11-20
      • 2013-05-15
      • 2011-08-20
      • 2012-03-04
      • 1970-01-01
      • 2011-05-18
      • 2012-12-21
      • 2012-04-03
      • 1970-01-01
      相关资源
      最近更新 更多