使用Maven在可执行jar中使用资源文件的相对路径问题

时间:2016-03-23 09:57:48

标签: java maven wordnet

我想制作一个jar文件,找出任务标签之间的相似之处。出于这个原因,我使用2个WordNet字典的Java库:JWNL-1.4-rc3JWI-2.3.3。我还在resources myProject文件夹中放置了JWNL库为了初始化而需要的properties.xml文件,以及WordNet词典:

src/main/resources/
    properties.xml
    WordNet-3.0/dict (dict has 24 files inside)

properties.xml文件的字典路径的值为:

<param name="dictionary_path" value="WordNet-3.0\dict"/>

在我的代码中,我有两个代码片段如下所示。

此代码初始化JWNL库:

try {
    JWNL.initialize(similarities.class.getClassLoader().getResourceAsStream("/properties.xml"));
}
catch (JWNLException e) {
    e.printStackTrace();
}

similarities是我的主要课程。

这是JWI词典的构造函数:

try {
    //String path = similarities.class.getProtectionDomain().getCodeSource().getLocation().getPath();
    dict=new Dictionary(this.getClass().getClassLoader().getResource("WordNet-3.0\\dict"));
    dict.open();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

但是当我导出一个可执行jar并在控制台中运行它时,我收到以下错误:

net.didion.jwnl.JWNLException: Properties file invalid or not found
at net.didion.jwnl.JWNL.initialize(JWNL.java:103)
at com.iteforth.annotationToBPM.similarities.main(similarities.java:576)
Exception in thread "main" java.lang.NullPointerException
at edu.mit.jwi.data.FileProvider.<init>(FileProvider.java:191)
at edu.mit.jwi.data.FileProvider.<init>(FileProvider.java:166)
at edu.mit.jwi.data.FileProvider.<init>(FileProvider.java:148)
at edu.mit.jwi.Dictionary.<init>(Dictionary.java:41)
at com.iteforth.annotationToBPM.similarities.<init>(similarities.java:92)
at com.iteforth.annotationToBPM.similarities.main(similarities.java:627)

我已经打开了我的jar文件,我已经检查了resources文件夹里面有properties.xml和WordNet字典。我也打开了MANIFEST,我看到类路径是:.(句号)

我已经阅读了很多关于这个问题的线程3天,但没有解决我的问题。我将不胜感激。

告诉我是否必须发送其他内容,例如POM.xmlproperties.xml个文件。

1 个答案:

答案 0 :(得分:1)

您所遇到的错误与属性文件的加载有关,但我认为您将获得另一个加载dictionnary的文件。

  1. 对于属性文件:

    JWNL.initialize(ClassLoader.getSystemResourceAsStream("properties.xml"));
    
  2. 确保您的文件位于jar的根目录中。如果您的源文件位于src / main / resources中,那就应该是这种情况,因为它是默认的maven配置。如果您的属性文件位于jar中的“resources”文件夹中,则会变为:

    JWNL.initialize(ClassLoader.getSystemResourceAsStream("resources/properties.xml"));
    
    1. 对于词典: API不是为了读取jar中的dictionnary文件而设计的。在第363行的edu.mit.jwi.data.FileProvider中,您会看到:

      File directory = toFile(url);
          if (!directory.exists()) 
              throw new IOException("Dictionary directory does not exist: " + directory);
      

      所以你必须把它们放在你的jar之外,在文件系统中:

      dict = new Dictionary(new File("WordNet-3.0\\dict"));
      dict.open();
      
    2. 注意: 当然,在代码中放置一个硬编码的绝对路径是个坏主意。

      如果您的jar总是从这个目录运行,您可以将dictionnary目录放在与jar相同的目录中,并使用上面代码中的相对文件路径访问它(参见How does Java resolve a relative path in new File()?

      或者您可以让用户使用命令行参数(https://docs.oracle.com/javase/tutorial/essential/environment/cmdLineArgs.html)或环境变量(https://docs.oracle.com/javase/tutorial/essential/environment/env.html)配置目录路径

      环境变量示例:

      • 用户定义一个环境变量,例如:

        set WORD_NET_DICTIONARY = "C:\WordNet-3.0\Dict"
        
      • 您可以在代码中获取此env变量并配置您的库:

        String wordNetDicDir = System.getenv("WORD_NET_DICTIONARY");
        if (wordNetDicDir != null) {
           dict = new Dictionary(new File(wordNetDicDir));
           dict.open();
        } else {
           // throw exception or log error
           ...
        }