gpt4 book ai didi

java - 是什么导致 Java 库在被 JRuby 调用时表现不同?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:30:33 26 4
gpt4 key购买 nike

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

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

此 Java 程序运行正常。

我在 Netbeans 中开发了下面的 Java 程序,然后按 F6(运行主项目)运行它。项目的库文件夹设置为“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"
}

}

这个 JRuby 程序的行为不正确。

我只需要输入 jruby bug_reproduce.rb 就运行了下面的 JRuby 程序。它打印了“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 文件。它们由 Microchip 作为 MPLAB X 的一部分提供并为其微 Controller 实现模拟器。 jar 文件随 MPLAB X 一起提供,我还下载了 MPLAB X SDK获得有关使用它们的帮助。我正在使用库的许多未记录的功能,但我没有看到任何替代方案。

我使用的是 Windows 7 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")验证我的两个程序都在 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()

    如果我按照 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.class"



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

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

    最佳答案

    我能够使用此实现获得预期的结果。此植入的主要区别在于将 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}"
    产出

    content/mplab/mplab.deviceSupport

    content/mplab/MPHeader.xml

    content/mplab/PluginBoardSupport.xml

    pins: 17

    关于java - 是什么导致 Java 库在被 JRuby 调用时表现不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15794170/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com