是什么导致Java库在被JRuby调用时表现出不同的行为?

是什么导致Java库在被JRuby调用时表现出不同的行为?,java,ruby,jruby,microchip,mplab,Java,Ruby,Jruby,Microchip,Mplab,我不熟悉Java世界,但熟悉Ruby。我正在尝试编写一个与一些第三方jar文件交互的程序 如果从Java调用这些库,它们的行为似乎很好,但当我在JRuby中调用它们时,它们的行为却不正确。这是一个问题,因为我真的很想使用JRuby。例如,以下两个程序尝试执行完全相同的操作,但它们产生不同的输出: 这个Java程序运行正常。 我在Netbeans中开发了下面的Java程序,并通过按F6(运行主项目)来运行它。项目的库文件夹设置为“C:\Program Files(x86)\Microchip\MP

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

如果从Java调用这些库,它们的行为似乎很好,但当我在JRuby中调用它们时,它们的行为却不正确。这是一个问题,因为我真的很想使用JRuby。例如,以下两个程序尝试执行完全相同的操作,但它们产生不同的输出:

这个Java程序运行正常。 我在Netbeans中开发了下面的Java程序,并通过按F6(运行主项目)来运行它。项目的库文件夹设置为“C:\Program Files(x86)\Microchip\MPLABX\mplab\u ide\lib\nblibraries.properties”。当我运行它时,它会打印“pins:17”

此JRuby程序的行为不正确。 我运行下面的JRuby程序,只需键入
JRuby bug\u repearch.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
更多细节 大约有80个第三方jar文件。它们由微芯片提供,作为微控制器的一部分,并为微控制器实现模拟器。jar文件随MPLAB X提供,我还下载了,以获得使用它们的帮助。我正在使用这些库的许多未记录的特性,但我看不到任何替代方案

我使用的是Windows7 64位SP1。我安装了以下与Java相关的东西,并在“程序和功能”下列出:

  • Java 7更新17
  • Java 7更新17(64位)
  • Java SE开发工具包7更新17(64位)
  • Java(TM)6更新22(64位)
  • Java(TM)6更新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”)
来验证我的两个程序是否都在Java1.6.0\u22下运行。这很好,因为我遵循了MPLAB X SDK中的说明,即“为了获得最佳结果,请使用与构建IDE/MDBCore的JDK完全相同的JDK。对于MPLAB X v1.70,这是Oracle的JDK 6u22。”在遇到此问题后,我才安装了JDK 7u17,这并没有什么区别

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

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

问题
  • 当从JRuby而不是Java调用JAR文件时,您知道有什么可能会导致JAR文件中的代码表现出不同的行为吗
  • JRuby1.7.3使用哪个版本的JDK,或者这个问题有意义吗
更新:已解决 感谢D3mon-1stVFW实际获得MPLAB X并为我解决了问题!对于那些对细节感兴趣的人来说:pin的数量是0,因为当使用PinSet.getPin(String)访问这些pin时,它们是延迟加载的。通常,所有管脚都会被加载,因为外围设备加载了它们,但在JRuby下,没有检测到任何外围设备。这是因为找不到periphal文档。这是因为PerDocumentLocator.findDocs()返回了一个空列表。PerDocumentLocator失败,因为
com.microchip.mplab.open.util.pathretrieval.pathretrieval.getPath(com.microchip.mplab.libs.MPLABDocumentLocator.MPLABDocumentLocator.class))
返回了错误的内容

考虑下面的代码,它与PathRetrieval.getPath中发生的情况类似(除了它是用Java编写的):

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

文件:C:/ProgramFiles(x86)/Microchip/MPLABX/mplab_ide/mplablibs/modules/com mi crochip-mplab-libs-MPLABDocumentLocator.jar/com/microchip/mplab/libs/MPLABDocum entLocator/MPLABDocumentLocator.class

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

文件:C:%5CProgram%20Files%20(x86)%5CMicrochip%5CMPLABX%5Cmplab_ide%5Cmplablibs% 5Cmodules%5Ccom-microchip-mplab-libs-MPLABDocumentLocator.jar/com/microchip/mpl ab/libs/MPLABDocumentLocator/MPLABDocumentLocator.class“

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

结论:有时Java会返回一个包含%5C而不是斜杠的URL,这会受到类路径上的内容的影响。如果您想安全起见,请在需要之前将jar文件添加到$CLASSPATH,如下所示:

require 'java'
$CLASSPATH << jar_filename
require jar_filename
require'java'

$CLASSPATH我能够使用此实现获得预期的结果。此植入的主要区别在于将JAR添加到类路径中。如果您对此行进行注释(
$CLASSPATH JRuby使用系统中安装的JDK。我想如果您愿意,您可以使用内置的JDK安装它。我注意到您在Java中调用
assemblyFactory.Create(…)
,方法名大写,但在Ruby中调用
assemblyFactory.Create(…)
。我知道JRuby会转换内部大写(驼峰大小写)变成下划线+小写字母,但我不确定它如何使用首字母大写。对我来说,最初的问题似乎是“太本地化”的海报男孩,因为答案是“配置文件从$CLASSPATH中丢失”。(现在,“为什么找不到我的资源?”
com.microchip.mplab.libs.MPLABDocumentLocator.MPLABDocumentLocator.java_class.resource("MPLABDocumentLocator.class").getFile()
require 'java'
$CLASSPATH << jar_filename
require jar_filename
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}"