1

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.

jadhachem
  • 1,123
  • 2
  • 11
  • 19
joan
  • 21
  • 7

1 Answers1

1

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
       ...
    }
    
Community
  • 1
  • 1
Hugo G.
  • 636
  • 6
  • 21
  • Thank you Hugo G. You solved my issue in 20 minutes and i had searched for it for 3 days!!! Could i ask something else too? I placed WordNet dictionary in C:/WordNet-3.0/dict directory. I want to import this jar file in a platform and run in anyone machine. I must create a readme txt which warns for placing WordNet dictionary in C: directory? – joan Mar 23 '16 at 11:16
  • That would be a bad idea : what if your user don't have a C letter drive or if he is on linux or mac ? I updated my answer with some ways to do that. – Hugo G. Mar 23 '16 at 11:45
  • I think that the better solution for my case is to use environment variable but i don't know how and i didn't understand the above link. I use a CLASSPATH variable with value: . (dot)(current working directory) and place it in the dictionary-path in properties.xml file: and in the dictionary constructor in java: dict = new Dictionary(new File("${CLASSPATH}WordNet-3.0\\dict")); But i have the following errors: The properties file must specify a dictionary path and Dictionary directory doesn't exits. Any idea how to use it? – joan Mar 23 '16 at 16:56
  • `CLASSPATH` does not denote a directory, it is a list of files and directories included in the java classpath. I added an example that uses a environnement variable to configure the location of the dictionnary. Please consider accepting the answer if it helped you. – Hugo G. Mar 29 '16 at 08:42
  • Sorry for the delay....the above example doesn't work because of the constructor of dictionary. It gets only URL or file and the wordNetDicDir is a String....Do you have any solution about this? Thanks in advance!!! – joan Apr 06 '16 at 08:59
  • File has a constructor that takes a String parameter as the path of the file. – Hugo G. Apr 06 '16 at 10:23
  • Thank you so much Hugo G.!!!! Something last... I also use a property.xml file for the JWNL library which contains the WordNet dictionary path with the value: '' How could i make dictionary_path in properties file independent of letter C driver to be used in any machine? – joan Apr 07 '16 at 08:27