我想创建一个简单的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>
步骤:
启动我的捆绑包 现在它引发了一个错误:
(LoadError)没有要加载的文件 - jruby / jruby.rb
当然,jruby / jruby.rb包含在jruby-complete.jar中,而不是我的示例包中
那么,我该怎么办?
答案 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?