当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Issue with relative paths of resources files in an executable jar using Maven

问题描述:

I want to make a jar file which finds similarities between task labels. For this reason I use 2 java libraries of WordNet dictionary: JWNL-1.4-rc3 and JWI-2.3.3. I also have placed, in the resources folder of myProject, the properties.xml file that is needed by JWNL library in order to be initialized, as well as the WordNet dictionary:

src/main/resources/

properties.xml

WordNet-3.0/dict (dict has 24 files inside)

The properties.xml file has the dictionary path with the value:

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

In my code, I have the two code snippets shown below.

This code initializes the JWNL library:

try {

JWNL.initialize(similarities.class.getClassLoader().getResourceAsStream("/properties.xml"));

}

catch (JWNLException e) {

e.printStackTrace();

}

similarities is my main class.

This is the constructor of the JWI dictionary:

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();

}

But when I export an executable jar and run it in the console, I get the following error:

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)

I have already opened my jar file and I have checked that there is a resources folder inside with the properties.xml and the WordNet dictionary. I also have opened MANIFEST and I have seen that the class path is: . (full stop)

I have read many threads about this issue for 3 days but nothing has solved my problem. I will appreciate any help.

Tell me if I must send something else, e.g., the POM.xml or properties.xml files.

网友答案:

The error you have is related to the loading of the properties file, but I think you will get an other one with the dictionnary loading.

  1. For the properties file:

    JWNL.initialize(ClassLoader.getSystemResourceAsStream("properties.xml"));
    

Be sure that your file is located at the root of your jar. That should be the case if your source file is in src/main/resources as it is the default maven configuration. If your properties file is in a "resources" folder in your jar as you said, this become :

JWNL.initialize(ClassLoader.getSystemResourceAsStream("resources/properties.xml"));
  1. For the dictionnary: The API is not designed to read dictionnary files inside the jar. In edu.mit.jwi.data.FileProvider at line 363, you would see:

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

    so you have to keep them outside your jar, in the filesystem :

    dict = new Dictionary(new File("WordNet-3.0\\dict"));
    dict.open();
    

Note: Of course, putting a hard coded absolute path in your code would be a bad idea.

You could put the dictionnary directory in the same directory as your jar, if your jar is always run from this directory, and access it with a relative file path in your code as above (see How does Java resolve a relative path in new File()?)

Or you could let the user configure the directory path with a command line arguments (https://docs.oracle.com/javase/tutorial/essential/environment/cmdLineArgs.html) or an environnement variable (https://docs.oracle.com/javase/tutorial/essential/environment/env.html)

Example with an environnement variable:

  • user define an environnement variable, for exemple :

    set WORD_NET_DICTIONARY = "C:\WordNet-3.0\Dict"
    
  • you can get this env variable in your code and configure your library:

    String wordNetDicDir = System.getenv("WORD_NET_DICTIONARY");
    if (wordNetDicDir != null) {
       dict = new Dictionary(new File(wordNetDicDir));
       dict.open();
    } else {
       // throw exception or log error
       ...
    }
    
分享给朋友:
您可能感兴趣的文章:
随机阅读: