动态Java程序的DLL?

动态Java程序的DLL?,java,dll,Java,Dll,我目前正在从事一个Java项目,在这个项目中,我有一组数据,希望以几种自定义格式输出。每种格式都有一个类,它获取原始数据并进行相应的转换。然而,首先,我只实现了其中的两到三种格式,但希望以后能够添加更多的格式,而无需对应用程序进行大规模重建 我的想法是为每个格式类创建一个DLL,并让我的应用程序传递要转换为每个格式类的数据。这样,我可以稍后创建一个DLL,并让我的主应用程序访问它。(我很乐意听取任何其他方法的建议,因为在此之前使用C++/C#的人认为这是一种逻辑解决方案,但它可能不适用于Java

我目前正在从事一个Java项目,在这个项目中,我有一组数据,希望以几种自定义格式输出。每种格式都有一个类,它获取原始数据并进行相应的转换。然而,首先,我只实现了其中的两到三种格式,但希望以后能够添加更多的格式,而无需对应用程序进行大规模重建

我的想法是为每个格式类创建一个DLL,并让我的应用程序传递要转换为每个格式类的数据。这样,我可以稍后创建一个DLL,并让我的主应用程序访问它。(我很乐意听取任何其他方法的建议,因为在此之前使用C++/C#的人认为这是一种逻辑解决方案,但它可能不适用于Java)

我的问题是,我完全不知道如何做到这一点——在C++/C中,我可以用几行代码来编写,但我不确定它在Java中是如何工作的。冒着问一个非常模糊的问题的风险,我该怎么做

非常感谢您的回答,我们将提供饼干和茶。:)

提前感谢,, M


编辑:抱歉,只是补充:我也不确定如何创建DLL,它必须在Java的这个项目,要在第一时间阅读。谢谢。:)

如果您想编写java中使用的本机代码(编译成DLL),请查看


更新您可以使用
System.loadLibrary(String libName)
(如果您知道库名称和库路径已设置)或
System.load(String filename)
(库文件名)在java中加载库(DLL)。

您可以随时使用System.loadLibrary()加载新的DLL。但是,您可能需要加载一个java类以将其绑定到

您可能会发现使用OSGi容器很有帮助,因为它支持模块(包括共享库)的加载和卸载

我建议在iPOJO中使用karaf,但还有很多其他的。

我做过这样的东西。 我创建了一个基于POJO的开放式java插件体系结构,它甚至可以在更新插件类的飞行中重新加载。 JNI是处理本机代码的接口。 唯一的技术部分是重写一个类加载器,使DLL能够在运行时动态重新加载。
但是如果你只进行“离线”更新,就不需要这样的东西了。

与其使用DLL本身,不如使用某种插件架构

除非有必要,否则我不建议使用DLL的一个原因是,将Java代码与本机代码链接将需要使用(JNI),这可能需要比纯Java解决方案更大的工作量

一种相对简单的方法是使用Java的功能

根据所提供的信息,我可能会遵循以下思路:

public interface Outputter {
  public void write(Data d);
}
// Note: We load the class by specifying the fully-qualified class name!
Class<?> clazz = Class.forName("TextOutputter");

// Then, we instantiate the class.
// Note that the following method will call the no-argument constructor.
Outputter outputter = clazz.newInstance();      

// Now, we can give data to the TextOutputter object that we loaded dynamically.
outputter.write(...);
  • 为输出格式定义一个接口
  • 创建一个实现接口的Java类
  • 让学生在教室里上课
  • 使用反射动态加载类。(使用该方法可以实例化
    ClassLoader
    加载的
    class
    文件中的对象)
  • 通过这些步骤,可以实现一个简单的插件,当需要支持新格式时,它不需要完全重建


    步骤1:定义接口

    假设我们最终得到如下界面:

    public interface Outputter {
      public void write(Data d);
    }
    
    // Note: We load the class by specifying the fully-qualified class name!
    Class<?> clazz = Class.forName("TextOutputter");
    
    // Then, we instantiate the class.
    // Note that the following method will call the no-argument constructor.
    Outputter outputter = clazz.newInstance();      
    
    // Now, we can give data to the TextOutputter object that we loaded dynamically.
    outputter.write(...);
    
    步骤2:创建一个实现类

    然后,我们将创建一个实现类

    public class TextOutputter {
      public void write(Data d) {
        // ... output data to text
      }
    }
    
    然后,编译上面的代码,我们将得到一个名为
    textoputter.class
    class
    文件

    步骤3:从类路径使类可用

    在运行主应用程序时,我们需要在。通常情况下,人们会告诉JVM一个要考虑的类列表作为类路径,并且应该包含上面的代码>类< /代码>文件。

    完成后,我们应该能够使用反射加载上述类

    步骤4:使用反射动态加载类

    现在,当我们真正想要加载上面的类时,我们将执行如下操作:

    public interface Outputter {
      public void write(Data d);
    }
    
    // Note: We load the class by specifying the fully-qualified class name!
    Class<?> clazz = Class.forName("TextOutputter");
    
    // Then, we instantiate the class.
    // Note that the following method will call the no-argument constructor.
    Outputter outputter = clazz.newInstance();      
    
    // Now, we can give data to the TextOutputter object that we loaded dynamically.
    outputter.write(...);
    
    //注意:我们通过指定完全限定的类名来加载类!
    Class clazz=Class.forName(“TextOutputer”);
    //然后,我们实例化这个类。
    //请注意,以下方法将调用无参数构造函数。
    Outputter Outputter=clazz.newInstance();
    //现在,我们可以将数据提供给动态加载的TextOutputter对象。
    输出。写入(…);
    
    该方法用于尝试从默认的
    ClassLoader
    中查找
    textoutputer
    类。一旦我们获得类作为表示,我们就可以实例化该类的对象

    可以使用该方法实例化对象。如果应该使用非无参数构造函数,则必须获取类的
    构造函数
    ,然后从中实例化对象

    然后,通过反射实例化的对象被放入
    Outputter
    变量中,因此可以在
    textoputter
    上调用
    write
    方法

    添加更多格式将需要上述过程,但加载不同的类只需更改完全限定的类名(例如,对于
    String
    ,FQCN是
    java.lang.String


    简而言之,这就是动态加载
    class
    文件并从应用程序中使用它所需要的


    (顺便说一句,我并没有编译上面的代码,所以这里和那里可能会有一些错误,但我希望我能说明它将需要的过程。)

    我认为您可以忽略JNI路径。我觉得你用dll这个词是因为没有更好的词,