什么原因导致Java库在JRuby调用时表现不同?

Dav*_*son 7 ruby java jruby microchip mplab

我是Java世界的新手,但我熟悉Ruby.我正在尝试编写一个与某些第三方jar文件交互的程序.

虽然从Java调用库似乎表现得很好,但是当我在JRuby中调用它们时它们的行为不正确.这是一个问题因为我真的想使用JRuby.例如,下面的两个程序尝试完全相同的东西,但它们产生不同的输出:

这个Java程序行为正常.

我在Netbeans中开发了下面的Java程序,然后按F6(运行主项目)运行它.项目的Libraries文件夹设置为"C:\ Program Files(x86)\ Microchip\MPLABX\mplab_ide\lib \nblibraries.properties".当我运行它时,它会打印"pins:17".

package pinbug1;    
import com.microchip.mplab.mdbcore.assemblies.Assembly;
import com.microchip.mplab.mdbcore.assemblies.AssemblyFactory;
import com.microchip.mplab.mdbcore.simulator.PinSet;
import com.microchip.mplab.mdbcore.simulator.Simulator;
import org.openide.util.Lookup;

public class PinBug1
{
    public static void main(String[] args)
    {
        AssemblyFactory assemblyFactory = Lookup.getDefault().lookup(AssemblyFactory.class);
        Assembly assembly = assemblyFactory.Create("PIC18F14K50");

        Simulator simulator = assembly.getLookup().lookup(Simulator.class);
        int num = simulator.getDataStore().getProcessor().getPinSet().getNumPins();
        System.out.println("pins: " + num);   // prints "pins: 17"
    }

}
Run Code Online (Sandbox Code Playgroud)

这个JRuby程序行为不正确.

我只需输入就运行下面的JRuby程序jruby bug_reproduce.rb并打印"pins:0".我希望它像Java程序一样打印"pins:17".

["mplab_ide/mdbcore/modules/*.jar",
 "mplab_ide/mplablibs/modules/*.jar",
 "mplab_ide/mplablibs/modules/ext/*.jar",
 "mplab_ide/platform/lib/org-openide-util*.jar",
 "mplab_ide/mdbcore/modules/ext/org-openide-filesystems.jar"
].each do |pattern|
  Dir.glob("C:/Program Files (x86)/Microchip/MPLABX/" + pattern).each do |x|
    require x
  end
end

assemblyFactory = org.openide.util.Lookup.getDefault.lookup(com.microchip.mplab.mdbcore.assemblies.AssemblyFactory.java_class)
assembly = assemblyFactory.create("PIC18F14K50")
simulator = assembly.getLookup.lookup(com.microchip.mplab.mdbcore.simulator.Simulator.java_class)
num = simulator.getDataStore.getProcessor.getPinSet.getNumPins
puts "pins: #{num}"    # => pins: 0
Run Code Online (Sandbox Code Playgroud)

更多细节

大约有80个第三方jar文件.它们由Microchip作为MPLAB X的一部分提供,并为其微控制器实现仿真器.jar文件随MPLAB X一起提供,我还下载了MPLAB X SDK以获得使用它们的帮助.我使用了大量未记录的库的功能,但我没有看到任何替代方案.

我使用的是Windows 7 64位SP1.我在"程序和功能"下安装并列出了以下与Java相关的内容:

  • Java 7 Update 17
  • Java 7 Update 17(64位)
  • Java SE开发工具包7更新17(64位)
  • Java(TM)6 Update 22(64位)
  • Java(TM)6 Update 29
  • Java(TM)SE开发套件6更新22(64位)
  • JRuby 1.7.3
  • IntelliJ IDEA社区版12.0.4
  • Netbeans IDE 7.3
  • MPLAB X IDE v1.70

我曾经System.getProperty("java.version")验证我的两个程序都在Java 1.6.0_22下运行.这很好,因为我按照MPLAB X SDK中的说明说"为了获得最佳结果,请使用构建IDE/MDBCore的完全相同的JDK,您的代码将与之交谈.对于MPLAB X v1.70,这是JDK 6u22来自甲骨文." 我遇到这个问题后才安装了JDK 7u17,并没有什么区别.

我能够找到示例中确定的特定问题的解决方法,但后来我继续我的开发并遇到另一个问题,其中库的行为不同.这让我觉得我在使用JRuby的方式上做了一些根本性的错误.

考虑到不同的类路径可能会导致此问题,我尝试让java程序打印出它的类路径,然后编辑我的JRuby程序以准确要求该列表中的文件,但它没有任何区别.

问题

  • 您是否知道在从JRuby而不是Java调用时,可能导致JAR文件中的代码行为不同的任何事情?
  • JRuby 1.7.3使用什么版本的JDK,或者这个问题是否有意义?

更新:已解决

感谢D3mon-1stVFW实际获得MPLAB X并为我解决了我的问题!对于那些对细节感兴趣的人:引脚数为0,因为当使用PinSet.getPin(String)访问它们时,引脚是延迟加载的.通常所有引脚都已加载,因为外设加载它们,但在JRuby下没有检测到外设.这是因为无法找到周围文件.这是因为PerDocumentLocator.findDocs()返回了一个空列表.PerDocumentLocator失败,因为com.microchip.mplab.open.util.pathretrieval.PathRetrieval.getPath(com.microchip.mplab.libs.MPLABDocumentLocator.MPLABDocumentLocator.class))返回错误的东西.

请考虑以下代码,它类似于PathRetrieval.getPath中发生的代码(除了它是用Java编写的):

com.microchip.mplab.libs.MPLABDocumentLocator.MPLABDocumentLocator.java_class.resource("MPLABDocumentLocator.class").getFile()
Run Code Online (Sandbox Code Playgroud)

如果我按照D3mon-1stVFW的提示并将JAR文件添加到$ CLASSPATH,那么该代码将返回:

file:C:/ Program Files(x86)/ Microchip/MPLABX/mplab_ide/mplablibs/modules/com-mi crochip-mplab-libs-MPLABDocumentLocator.jar!/ com/microchip/mplab/libs/MPLABDocum entLocator/MPLABDocumentLocator.class

但是,如果我不向类路径添加内容,那么该代码奇怪地返回:

file:C:%5CProgram%20Files%20(x86)%5CMicrochip%5CMPLABX%5Cmplab_ide%5Cmplablibs%5Cmodules%5Ccom-microchip-mplab-libs-MPLABDocumentLocator.jar!/ com/microchip/mpl ab/libs/MPLABDocumentLocator/MPLABDocumentLocator.类"

%5C实际上是反斜杠的代码.PathRetrieval.getPath中的Microchip代码执行了大量字符串操作,并且无法正确处理由%5C表示斜杠的情况.如果有人对%5Cs出现的原因有任何进一步的了解,我很想知道,但我的问题已经解决了.

结论:有时Java的getResource()返回一个带有%5C而不是斜杠的URL,这受到CLASSPATH上的内容的影响.如果您想要安全,请在需要之前将jar文件添加到$ CLASSPATH,如下所示:

require 'java'
$CLASSPATH << jar_filename
require jar_filename
Run Code Online (Sandbox Code Playgroud)

Hit*_*eeb 4

我能够使用此实现获得预期结果。此植入的主要区别是将 jar 添加到类路径中。如果您评论此行 ( $CLASSPATH << jar_file),您将获得 0 个引脚。(问题底部有解释)

require 'java'

Dir.glob("C:/MyCustomLibraries/MATLAB/*.jar").each do |jar_file| #Has all MPLab jars except org.netbeans.*
  $CLASSPATH << jar_file
  require jar_file
end

module Mplab
  include_package "org.openide.util" #Lookup
  include_package "com.microchip.mplab.mdbcore.simulator" #PinSet, Simulator
  include_package "com.microchip.mplab.mdbcore.assemblies" #Assembly, AssemblyFactory
end

assembly_factory = Mplab::Lookup.getDefault.lookup(Mplab::AssemblyFactory.java_class)
assembly = assembly_factory.create("PIC18F14K50")
simulator = assembly.getLookup.lookup(Mplab::Simulator.java_class)
num = simulator.getDataStore.getProcessor.getPinSet.getNumPins
puts "pins: #{num}" 
Run Code Online (Sandbox Code Playgroud)

输出

内容/mplab/mplab.deviceSupport

内容/mplab/MPHeader.xml

内容/mplab/PluginBoardSupport.xml

引脚:17