gpt4 book ai didi

java - 将.jar库的 native 库(.dll)添加到IntelliJ中的工件中

转载 作者:行者123 更新时间:2023-12-01 16:51:27 27 4
gpt4 key购买 nike

我一直在论坛中寻找与我的问题相关的问题,但没有找到任何内容。对此的任何帮助将不胜感激。

我有一个使用 IntelliJ 的 Java 应用程序,其中包含库 RXTXcomm.jar,该库附带一个 native 库 rxtxSerial.dll,两者都位于单独的文件中。

通过正确设置 RXTXcomm.jar 库的依赖项并将项目结构的“依赖项”部分中的 rxtxSerial.dll 设置为 native 库位置,我在项目中使用了该库,没有出现任何问题。

当我想生成项目的工件时,问题就出现了。我已经使用不同的项目创建了许多工件,但这是我第一次必须向工件添加带有 native .dll 库的库。从项目结构/工件中,我双击 RXTXcomm.jar,就像在项目结构/模块/依赖项部分中一样,添加 rxtxSerial.dll,但当然它不起作用。我尝试将 .dll native 库添加到工件中,就像我之前添加的任何其他 .jar 库一样,但它不起作用。当我运行我的工件时,抛出以下错误:

Image of exception thrown when running the artifact

我认为问题在于我如何将此库添加到工件中,但我找不到如何在网络上进行此搜索。如果阅读有关 NativeUtils 类的信息,但我认为这不是我在这里需要的,因为更多的是工件配置问题。在这里,我向您展示如何添加 RXTXcomm.jar 及其 native 库以使其在 IDE 中运行: Library added in Project Structure/Modules/Dependencies

这样,从 IDE 运行应用程序一切就完美了。

现在这是我添加库及其 native 来构建工件的方法: Library added in Project Structure/Artifacts

我肯定在这里做错了什么,但找不到什么。在我的工件中将此 native 库 (rxtxSerial.dll) 添加到 RXTXcomm.jar 库以避免出现此异常并使其正常工作的正确方法是什么?

任何帮助将不胜感激,如果需要更多信息,请告诉我。

非常感谢,

丹尼尔。

编辑:按照@Andrey的建议,我尝试按照他提供的链接中解释的方式加载.dll库:How to make a JAR file that includes DLL files? ,但它似乎对我不起作用,我不明白为什么。这是我使用过的代码:

public class Main extends Application {
private static DataBase database= new DataBase();
private final static Log logger = LogFactory.getLog(ACWrapper.class);
private static final String LIB_BIN = "/lib-bin/";
private final static String rxtxSerial = "rxtxSerial";
/**
* Function to launch the application
* @param args .
*/
public static void main(String[] args) {
// Merge the Swing and JavaFX threads - needs Java 8
//System.setProperty("javafx.embed.singleThread", "true");

// Verify that Direct3D is enabled (the default setting), to avoid resize issues.
try {
if (Boolean.valueOf(System.getProperty("sun.java2d.noddraw", "false")) ||
!Boolean.valueOf(System.getProperty("sun.java2d.d3d", "true"))) {
throw new IllegalStateException("Do not change the Direct3D default settings (Windows specific), "
+ "it may cause glitches during frame re-sizing.");
}

Application.launch(args);
} catch (IllegalStateException ex){
ex.printStackTrace();
database.insertSystemErrorLog(Thread.currentThread().getStackTrace()[1].getMethodName(),ex);
}
}

/**
* Function to configure the stage where the view will be added
* @param primaryStage the stage to be configured
*/
@Override
public void start(Stage primaryStage) {

try {
if (!EventQueue.isDispatchThread()) {
throw new IllegalStateException(
"FX and Swing thread should be merged. Are you using Java 8 and the javafx.embed.singleThread flag?");
}

loadExternalDllFiles();

//Add Swing view and interface components to the FX frame
SwingNode viewNode = addSwingNodeToFXFrame(primaryStage);
//----------------------------------------------

//Add FX view and interface components to the FX frame

//----------------------------------------------

// Auxiliary panel with provisional content
Accordion auxiliaryPanelFX = new Accordion();

// Do the lay-out using FX
HBox hbox = new HBox(viewNode, auxiliaryPanelFX);
HBox.setHgrow(viewNode, Priority.ALWAYS);

// Show the window
primaryStage.setScene(new Scene(hbox));
primaryStage.setFullScreen(true);
primaryStage.setTitle("FXApp");
primaryStage.setResizable(true);
primaryStage.show();

} catch (IllegalStateException ex){
ex.printStackTrace();
database.insertSystemErrorLog(Thread.currentThread().getStackTrace()[1].getMethodName(),ex);
}

}

private void loadExternalDllFiles() {
logger.info("Loading DLL");
try {
System.loadLibrary(rxtxSerial);
logger.info("DLL is loaded from memory");
} catch (UnsatisfiedLinkError e) {
loadFromJar();
}
}

/**
* When packaged into JAR extracts DLLs, places these into
*/
private static void loadFromJar() {
// we need to put both DLLs to temp dir
String path = "AC_" + new Date().getTime();
loadLib(path, rxtxSerial);
}

/**
* Puts library to temp dir and loads to memory
*/
private static void loadLib(String path, String name) {
name = name + ".dll";
try {
// have to use a stream
InputStream in = ACWrapper.class.getResourceAsStream(LIB_BIN + name);
// always write to different location
File fileOut = new File(System.getProperty("java.io.tmpdir") + "/" + path + LIB_BIN + name);
logger.info("Writing dll to: " + fileOut.getAbsolutePath());
OutputStream out = FileUtils.openOutputStream(fileOut);
IOUtils.copy(in, out);
in.close();
out.close();
System.load(fileOut.toString());
} catch (Exception e) {
System.out.println("Failed to load required DLL");
}
}

/**
* Function to create a SwingNode with all the components using Swing format
* @param primaryStage_ JavaFX Stage where all the Swing components will be added
* @return The SwingNode already built
*/
private SwingNode addSwingNodeToFXFrame(Stage primaryStage_) {

//Set the initial language of the application
Locale locale = new Locale("en", "GB");
LanguageConfiguration.setLanguageSelected(locale);
LanguageConfiguration.setKeyboardLanguage(LanguageConfiguration.KeyboardLanguage.LATIN);

//Create all interface components and add it to the view
InterfaceControlsManager interfaceControlsManager = new InterfaceControlsManager();
TLspSwingView view = interfaceControlsManager.loadSwingInterfaceControls();

// Wrap the Swing view in an FX node so it can be added to the FX hierarchy
SwingNode viewNode = new SwingNode();
viewNode.setContent(view.getHostComponent());

// Clean-up the view when the window is closed
primaryStage_.setOnCloseRequest(event -> view.destroy());

return viewNode;
}

当我调用 loadExternalDllFiles(); 时,我开始加载 .dll 文件 (rxtxSerial.dll),当我看到控制台中打印的信息时,它似乎已正确添加,其中打印消息“DLL 已从内存加载”。打印后,我收到与之前上传的图片相同的错误。这是我现在得到的: Error thrown after load the .dll file

请注意,我要添加的 .jar 库 RXTXcomm.jar(它允许我读取 GPS 帧)及其 native 库 rxtxSerial.dll 位于单独的文件中,因此 .dll 未打包在 .我想是 jar 。请参阅下图,了解使用上图中显示的工件配置创建该工件时其文件夹中的内容: RXTXcomm.jar and rxtxSerial.dll in the artifact folder

抱歉问题太长。我试图提供尽可能多的信息,因为这让我发疯......

最佳答案

最后,我找到了一种方法,当我尝试运行带有 RXTXcomm.jar 库的 .jar 应用程序时,不会出现此异常。

我已按照此链接 rxtx.qbang.org 的说明进行操作,“unjar 部分”,来自 RXTXcomm 库 wiki。我已经解压了 RXTXcomm.jar 库,因为它是一个 .zip 或 .rar 文件,并且它解压缩了一个名为 gnu 的文件夹。我需要做的正是我在配置“项目结构/工件”中的工件时在问题图像中所做的事情。

构建工件后,我必须转到工件文件夹并粘贴从 RXTXcomm.jar 文件解压缩中检索到的 gnu 文件夹。

粘贴gnu文件夹后,我只需要使用命令行转到工件的路径并运行(仅第一次)命令:

jar uvf Your_Apps_Name_here.jar gnu

就我而言,“Your_Apps_Name_here.jar”是我的 FOMAD.jar。它将像这样聚合它的类: Adding gnu package

运行此命令后,仅在创建工件时运行一次,现在我可以随时运行我的应用程序,无论出现任何问题,在执行过程中 RXTXcomm.jar 库都不会出现错误,就像以前一样(一如既往地运行:“java -jar MyApplication.jar”)。

关于java - 将.jar库的 native 库(.dll)添加到IntelliJ中的工件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61679461/

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