模块化Java应用程序

模块化Java应用程序,java,eclipse,maven,jar,decoupling,Java,Eclipse,Maven,Jar,Decoupling,我试图将我的项目分成两个不同的罐子。第一个是具有所有业务逻辑的“核心”jar。第二个是命令提示符版本,它将使用core。以下是包含内容和代码段的项目结构 CoreApp项目结构 CoreApp - src - com.myapp.service - CoreService.java - lib - thirdPartyX.jar - coreFile.txt CmdLineApp - src - com.myapp.main -

我试图将我的项目分成两个不同的罐子。第一个是具有所有业务逻辑的“核心”jar。第二个是命令提示符版本,它将使用core。以下是包含内容和代码段的项目结构

CoreApp项目结构

CoreApp
  - src
    - com.myapp.service
      - CoreService.java
  - lib
    - thirdPartyX.jar
  - coreFile.txt
CmdLineApp
  - src
    - com.myapp.main
      - MainClass.java
  - lib
    - thirdPartyY.jar
    - coreApp.jar
  - input.txt
CmdLine项目结构

CoreApp
  - src
    - com.myapp.service
      - CoreService.java
  - lib
    - thirdPartyX.jar
  - coreFile.txt
CmdLineApp
  - src
    - com.myapp.main
      - MainClass.java
  - lib
    - thirdPartyY.jar
    - coreApp.jar
  - input.txt
MainClass.java

public class MainClass {
  pulic static void main(String[] args) {
    File inputFile = new File("input.txt"); //OK
    ...
    coreService.doSomething(); //ERROR
  }
}
public class CoreService {
  public void doSomething() {
    File coreFile = new File("coreFile.txt"); //NOT OK 
    ...
  }
}
CoreService.java

public class MainClass {
  pulic static void main(String[] args) {
    File inputFile = new File("input.txt"); //OK
    ...
    coreService.doSomething(); //ERROR
  }
}
public class CoreService {
  public void doSomething() {
    File coreFile = new File("coreFile.txt"); //NOT OK 
    ...
  }
}
我面临两个问题:

  • cmdLineApp中没有thirdPartyX.jar,即使我有coreApp.jar。(现在,作为替代lib目录中coreApp.jar的解决方法,我将在STS中的CmdLineApp的构建路径中添加coreApp项目)

  • 运行main()方法时,应用程序可以访问/查找input.txt,但不能访问/查找coreFile.txt。(我不想把coreFile.txt放在CmdLineApp项目中,因为它只在core中使用)

  • 因此,我的问题是,我如何在不必写入/硬编码绝对路径的情况下获取文件。以及如何在这种项目结构中组织jar和第三方jar

    拥有独立核心的原因是我也将开发基于web的版本,其中我将使用来自控制器的核心服务方法。所以cmd行和基于web的都将使用相同的核心代码

  • cmdLineApp中没有thirdPartyX.jar,即使我有coreApp.jar。(现在,作为替代lib目录中coreApp.jar的解决方法,我将在STS中的CmdLineApp的构建路径中添加coreApp项目)
  • 大多数“Pro”应用程序通过使用相应的类路径设置实例化自己的
    ClassLoader
    来处理这个问题。通常使用
    URLClassLoader
    完成此操作。他们将把额外的
    .jar
    存档存储在
    lib/
    目录中。您可以编写创建
    URLClassLoader
    的代码,使其能够拾取
    .jar
    目录中的任何
    lib/
    文件,因此,如果添加、删除或重命名
    .jar
    文件,您无需触摸该代码

    如果
    .jar
    文件是插件,那么您甚至可以在
    java.nio.file.WatchService
    中使用第二个
    ClassLoader
    ,以便在运行时检测对
    .jar
    存档的更改

  • 运行main()方法时,应用程序可以访问/查找input.txt,但不能访问/查找coreFile.txt。(我不想把coreFile.txt放在CmdLineApp项目中,因为它只在core中使用)
  • 如果您只需要读取该文件,请将该文件作为资源放在.jar文件中,并使用
    getClass().getResourceAsStream()
    getClass().getResource()
    访问该文件。注意,它将不再是
    文件
    ,而是
    输入流
    URL
    ,但如果您是只读的,这应该无关紧要


    如果需要写入此文件,可以使用前面的方法,将数据存储在一个临时文件中,可以使用
    file.createTempFile()
    创建临时文件,并使用
    java.util.prefs.Preferences

    加载*.jar的代码和使用URLClassLoader的文件应位于CoreApp或CmdLine项目中?这取决于具体情况。如果您的CmdLine加载了您的CoreApp,CoreApp将加载重置,那么两者中都会有这样的代码。-我不确定“重置”是什么意思,但CmdLine将只使用MainClass.java中所示的服务。很抱歉,这是一个拼写错误,应该是“rest”。