jruby编写java_使用Java Web Start部署JRuby应用程序

jruby编写java

要进入Ruby和Java的统一世界,您需要一个命令: include Java

这将允许您实例化Java类,调用它们的方法,甚至从它们派生就好像它们只是普通的Ruby对象一样。 有一些细微的差异,本文将向您展示如何管理它们,以便您可以快速设计新应用程序并将其以闪电般的速度部署到用户。

本文基于一个示例应用程序,该示例应用程序使用JRuby和Swing实现了一个简单的ObjectSpace浏览器。 Ruby的ObjectSpace功能提供了一种访问系统中所有对象的方法。 例如,所有活动字符串都可以这样打印:

ObjectSpace.each_object(String) do |string|
 puts string
end
从我的irb会话中运行时,这将产生大约28000个字符串。 使用Swing和JRuby,我们现在可以在一个漂亮的图形界面中显示不同的类,它们的实例和可用的方法。 您甚至可以通过在最右边的面板中单击无参数方法来调用它们:

默认情况下,JRuby对ObjectSpace的支持是禁用的,因为它会影响运行时的性能,但稍后会对此进行更多说明。

我想指出一些有趣的实现细节,并给出一些有关如何开始使用JRuby的Java集成功能的提示。

Java整合

将Java包含在脚本中之后,就可以开始对现有Java类进行子类化。 只需指定Java类的标准名称即可完成此操作。 在示例应用程序中,主窗口扩展了JFrame。 它还将javax.swing和java.awt包包含在类的范围内,因此您不必为每种用法指定全名:

class MainWindow < javax.swing.JFrame
include_package 'javax.swing'
include_package 'java.awt' ...

另外,您也可以使用include_class函数包含特定的类,该函数不会用您永远不会使用的类的常量来污染名称空间。

调用超级构造函数的工作方式与普通的Ruby代码相同,这意味着可以通过在initialize -method的第一行调用super("JRuby Object Browser")来设置框架标题。

在类中包含整个javax.swing包之后,实例化Java类非常简单:

list_panel = JPanel.new
list_panel.layout = GridLayout.new(0, 3)

如果您仔细看一下第二行,可能会认为我们直接访问了JPanel的layout-field,但是事实并非如此。 JRuby在Java对象中添加了一些便捷方法,因此上面的语句也可以按照习惯的方式编写:

list_panel.setLayout(GridLayout.new(0, 3))

似乎可以直接访问字段,而不是使用getter和setter。 JRuby在Java对象中添加了更多的语法糖,使整个体验看起来更像Ruby:对于任何方法调用,您都可以使用snake_case表示法代替实际定义的驼峰案例名称。 从这开始,采用第三种方式调用setLayout方法:

list_panel.set_layout(GridLayout.new(0, 3))

从自己的类中调用setter方法时要谨慎,Ruby可能会认为您想创建一个局部变量,因此必须以self作为接收者显式地调用它:

self.default_close_operation = WindowConstants::EXIT_ON_CLOSE

Java和Ruby之间的另一个区别是常量的访问,例如上一EXIT_ON_CLOSE中的EXIT_ON_CLOSE 。 只是记得要全部更换. 如果您要将某些代码从Java转换为Ruby,请使用::访问。

到目前为止,JRuby带给Swing开发的大多数变化似乎都不是革命性的,但是我们还没有涉及一个重要方面:侦听器。 在Java中,用事件连接侦听器通常意味着在匿名类中实现接口:

button.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent e) {
 ...
}
});

如果您需要附加大量的侦听器,这确实会使您的代码混乱。 使用JRuby,可以将其简化为以下两行代码(如果不使用它,甚至可以省略event变量):

button.add_action_listener do |event|
...
end

这些是开始将Swing与JRuby结合使用所需的基本知识。 尽管JRuby使使用Swing进行GUI开发更加舒适,但是您仍然必须手动编写大量代码,尤其是当您需要使用复杂的布局时。 如果想使Swing-UI的创建更加简单,请看一下JRuby GUI API的三种方法

轻松部署JRuby应用程序

Ruby应用程序和库通常是在RubyGems的帮助下分发的,但是要利用它,您已经需要安装Ruby和RubyGems,这对于一般的最终用户而言并非如此。 对于传统的(MRI / C-Ruby)程序,已经以RubyScript2Exe [1]的形式解决了该问题,该程序将您的脚本和Ruby解释器捆绑到一个可以在多个平台上运行的好程序包中。 JRuby的用户不必被雨淋湿,相反,他们手头有一个甚至更强大的工具可以快速部署应用程序:Java Web Start。

Java Web开始救援

Java Web Start包含在Java运行时环境中,因此应该在大多数系统上都存在。 使应用程序为Web Start做好准备非常容易,所需要做的就是一个包含所有文件的Jar和一个JNLP(Java网络启动协议)描述文件。 我们演示了基于ObjectSpace浏览器应用程序创建可Web启动的Ruby应用程序的过程。

Web Start的先决条件是一个包含应用程序的Jar,因此我们将首先对其进行介绍。 JRuby提供了两个不同的库:“最小” jruby.jar和jruby-complete.jar,它们捆绑了整个Ruby标准库。 如果您不使用标准库中的任何内容,则可以使用较小的jruby.jar,并将下载量减少大约1 MB。

使脚本运行的最简单方法是将.rb文件添加到jruby.jar。 以下命令将我们的示例rob.rb添加到zip中。

jar uf jruby.jar rob.rb

要检查它是否有效,您可以使用Java来启动您的应用程序,需要我们的Ruby脚本。 应用程序需要ObjectSpace,我们需要通过将jruby.objectspace.enabled=true属性传递给Java来启用它:

java -Djruby.objectspace.enabled=true -jar jruby.jar -r rob

-r选项自动需要指定的文件,并因此运行我们的脚本。

提前进行时间编译

JRuby 1.1令人兴奋的新功能之一是提前(AOT)编译支持。 当前,JRuby中的即时编译仅限于2048个方法 ,提前编译可以减轻这种限制jrubyc (JRuby编译器)仍在开发中,因此,我建议使用可用的最新JRuby版本。 将纯Ruby文件编译为类文件就像使用脚本作为参数调用编译器一样简单:

jrubyc rob.rb

这将创建一个包含rob.class文件的ruby目录。 与其像上面那样在ruby.jar中包含ruby目录,我们将创建一个单独的Jar来保存应用程序。 毕竟,修改现有的Jar似乎并不是一个很好的解决方案。 罐子可以用相同名称的工具制成:

jar -cfe rob.jar ruby/rob.class ruby
这将创建一个名为rob.jar的小Jar,其中包含我们的类,并将ruby / rob.class添加为要在清单中指定的主类。 这使我们可以简化调用,因为我们现在可以简单地指向该类,而不必再在命令行中专门化需求了。 要执行它,我们必须确保rob.jar在类路径上:
java -Djruby.objectspace.enabled=true -cp rob.jar:jruby.jar ruby.rob
网页开始

在继续编写JNLP文件之前,我们需要对Jars进行签名。 不幸的是,这是必需的,因为JRuby使用反射,因此需要具有扩展的权限,有关更多详细信息 ,请参见JRuby Wiki 。 最简单的方法是使用JDK随附的keytool创建自己的测试证书:

keytool -genkey -keystore myKeystore -alias myself
keytool -selfcert -alias myself -keystore myKeystore

从现在开始,每次修改其中一个Jar时,都必须更新签名,否则在运行它时会收到SecurityException。

jarsigner -keystore myKeystore jruby.jar myself
jarsigner -keystore myKeystore rob.jar myself

现在我们已经准备好了Jars,我们可以实际查看该JNLP文件了。 下面介绍了该应用程序的最小配置。 规范要求一些字段,例如titlevendorj2se标签以及security部分。 罐子标签表示罐子的最终位置。 它还可以使用file:// -URL指向本地文件,这在开发过程中很方便。 这里也需要设置ObjectSpace属性,这可以通过property-tag来完成。

<?xml version="1.0" encoding="utf-8"?>
<jnlp>
<information>
<title>Ruby Object Browser</title>
<vendor>Mirko Stocker</vendor>
</information>
<resources>
<jar href="http://misto.ch/rob/rob.jar"/>
<jar href="http://misto.ch/rob/jruby.jar"/>
<j2se version="1.5+"/>
<property name="jruby.objectspace.enabled" value="true"/>
</resources>
<application-desc main-class="ruby.rob"/>
<security>
<all-permissions/>
</security>
</jnlp>

如果您跳过了AOT部分,或者只是想保持单一方式,则必须修改jnlp文件以包含-e参数,因此application-desc如下所示:

[...]
<application-desc>
<argument>-r</argument>
<argument>rob</argument>
</application-desc>
[...]

最后一步是将Jars和JNLP文件上传到指定位置。 现在,您应该能够在浏览器中打开链接,或者直接从外壳中使用javaws工具打开链接。

故障排除

为了使您的浏览器通过Web Start启动应用程序,JNLP文件需要与application/x-java-jnlp-file MIME-Type一起提供。 因此,如果您的浏览器仅显示JNLP文件的内容,而javaws没有自动启动,则需要调整Web服务器配置。 例如,Apache在mime.types中需要以下指令:

application/x-java-jnlp-file jnlp

进一步阅读

JRuby Wiki是获取有关JRuby常规信息的理想资源。

  1. http://www.erikveen.dds.nl/rubyscript2exe/

下载Ruby Object Browser代码。

翻译自: https://www.infoq.com/articles/jruby-deployment-with-webstart/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

jruby编写java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java.lang.NoClassDefFoundError: org/jruby/javasupport/proxy/InternalJavaProxy是一个Java错误,表示在运行时找不到指定的类。这个错误通常发生在类路径配置错误或者缺少所需的依赖项的情况下。 解决这个错误的方法有以下几种: 1.检查类路径配置:确保所需的类或依赖项在类路径中正确配置。可以通过以下命令查看当前的类路径配置: ```shell echo $CLASSPATH ``` 如果类路径配置不正确,可以使用以下命令来设置类路径: ```shell export CLASSPATH=/path/to/your/classpath ``` 请将"/path/to/your/classpath"替换为正确的类路径。 2.检查依赖项:确保所需的依赖项已经正确地包含在项目中。可以通过以下方式检查依赖项: - 如果使用Maven进行构建,可以检查项目的pom.xml文件,确保所有依赖项都正确声明。 - 如果使用Gradle进行构建,可以检查项目的build.gradle文件,确保所有依赖项都正确声明。 - 如果手动管理依赖项,可以检查项目的lib目录,确保所有依赖的jar文件都存在。 3.检查编译和运行环境:确保编译和运行环境的一致性。如果使用不同版本的Java编译和运行代码,可能会导致类定义不匹配的错误。请确保编译和运行代码的Java版本一致。 4.检查类加载器:如果使用自定义类加载器加载类,可能会导致类路径配置错误或者类加载器本身存在问题。请检查类加载器的实现,并确保它正确加载所需的类。 5.检查类文件:如果类文件本身存在问题,可能会导致NoClassDefFoundError错误。请确保类文件存在,并且没有被损坏或者被修改。 这些是解决java.lang.NoClassDefFoundError错误的常见方法。根据具体情况,您可以尝试其中的一种或多种方法来解决该错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值