• Post Reply Bookmark Topic Watch Topic
  • New Topic

External JAR's and classpath for Servlets  RSS feed

 
Ahmed Faisal
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everyone,
Am using Tomcat-8 with Eclipse_EE.
I am trying to use some external JAR's of Stanford NLP POS tagger found here (http://nlp.stanford.edu/software/tagger.shtml). And following the tutorial on the link (http://www.galalaly.me/index.php/2011/05/tagging-text-with-stanford-pos-tagger-in-java-applications/) I created following Java class in Dynamic Web Page project to test if POS Tagger is working or not:



It works perfectly as far as code is run as Java application and shows the following output.
This_DT is_VBZ a_DT sample_NN ._.

It Means, as a pure Java class in Dynamic Web Page project, it runs fine and shows the output. But when I create a Servlet in the same project and create an object of the Tagger class(Posted above) in the newly created servlet, it doesn't work. My Servlet looks like as follows:


My Stack Trace prints like following on the console windows:



As it is mentioned in Stack Trace that it could be problem of either class path or missing class so I searched online and found full version of POS Tagger here (http://nlp.stanford.edu/software/stanford-corenlp-full-2015-01-29.zip). Desperately, I put every file (model and JAR's) in lib folder of my web project thinking that my servlet can find missing classes if any. My folder structure looks like as follows:


About the classpath environment variable, I have following paths in it:
"C:\apache-tomcat-8\apache-tomcat-8.0.20\lib\servlet-api.jar;C:\Users\Faisal\workspace_EE\webProj1\WebContent\WEB-INF\lib;"

I have done whatever I could do to have a breakthrough in this problem but the error is there as I have listed above. Please guide me through this problem and also educate me if I am lacking some info. However I am also reading some sources that could help me finding the problem at
http://www.doc.ic.ac.uk/csg-old/java/servlets/servlets.html), (http://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.htmlhttp://en.wikipedia.org/wiki/Classpath_(Java)
http://www-nlp.stanford.edu/nlp/javadoc/javanlp/edu/stanford/nlp/tagger/maxent/MaxentTagger.html
http://www.tutorialspoint.com/servlets/servlets-environment-setup.htm
https://www.mulesoft.com/tcat/tomcat-classpath#solutions

Maybe somebody else can get something from the above sources that I missed. Please don't hang up on me. I really need to break through this problem. A lot of thanks, in advance for any effort/clue/idea even if you're not sure about it.
God bless you all.
 
Stefan Evans
Bartender
Posts: 1836
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ahmed, welcome to the ranch.

It looks like you need to add these ".tagger" files to your web application's classpath and load them appropriately.

A web application's classpath is
- files in the WEB-INF/classes directory
- jar files in the WEB-INF/lib directory
So right now the ".tagger" files aren't in the classpath, and your code is trying to access them from the web root which also doesn't work.

My suggestions:
Create a "classes" folder under WEB-INF
Move the .tagger and .tagger.props files from WEB-INF/lib to WEB-INF/classes. There should only be ".jar" files in the lib directory.

Change your initialization code to


That should at least give you a different error message :-)
 
Ahmed Faisal
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stefan Evans wrote:Hi Ahmed, welcome to the ranch.

It looks like you need to add these ".tagger" files to your web application's classpath and load them appropriately.

A web application's classpath is
- files in the WEB-INF/classes directory
- jar files in the WEB-INF/lib directory
So right now the ".tagger" files aren't in the classpath, and your code is trying to access them from the web root which also doesn't work.

My suggestions:
Create a "classes" folder under WEB-INF
Move the .tagger and .tagger.props files from WEB-INF/lib to WEB-INF/classes. There should only be ".jar" files in the lib directory.

Change your initialization code to


That should at least give you a different error message :-)

Thanks Stefan,

I moved .tagger and .tagger.props files from WEB-INF/lib to WEB-INF/classes and now my directory structure looks like this.



However, the Tagger class isn't working by itself either as it was working before. Regardless of what initialization code I use from following:

OR




I am getting the following exception on the console.




I am keeping my environment CLASSPATH variable same as before because changing it to "...\WEB-INF\classes" doesn't change anything.
However, I did notice that the Stack Trace is "Unable to resolve "WebContent\WEB-INF\lib\english-left3words-distsim.tagger"", which is why the Tagger class working before because the .tagger and .tagger.props files were in "\WEB-INF\lib". I am not disagreeing with you on the fact that only jar files should be in "\WEB-INF\lib". I am trying to say that there is something I have messed up due to which, compiler tries to find .tagger files in "\WEB-INF\lib". Because, when I moved classes back to "\WEB-INF\lib", tagger class worked fine as Java application but same stack trace shows up in the servlet. Remember that compiler sees .tagger files in \lib folder even if I change CLASSPATH environment variable's value to "\WEB-INF\classes". Hope this info will help you to find out the problem.
 
Stefan Evans
Bartender
Posts: 1836
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, I'm still waking up here.
You get stuff into the "classes" folder by having it in your source (duh!)

So my new suggestions are:

- make a folder "taggers" under src
- copy those tagger/properties file into src/taggers.



Theoretically that should work for both your app, and your webapp.
 
Ahmed Faisal
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stefan Evans wrote:Sorry, I'm still waking up here.
You get stuff into the "classes" folder by having it in your source (duh!)

So my new suggestions are:

- make a folder "taggers" under src
- copy those tagger/properties file into src/taggers.



Theoretically that should work for both your app, and your webapp.


Ok. So I created a new folder src/taggers and put .taggers and .props files into that. The folder structure looks like this:



By the way, I don't know why the "taggers" icon looks different than other folders, however I created it as folder by right clicking on /src and new->others->folder.

Unfortunately, it's still not working and showing the exact same Stack Trace exception as follows:


Like I said before, compiler looks .tagger files into \lib folder as it is mentioned in stack trace at line 7. But I honor your suggestions to work around this problem.
 
Tim Holloway
Bartender
Posts: 18777
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My vision is a bit blurry today and I can't follow all that, but two things ring alarm bells:

1. Any question that starts with "I'm running XXX with YYY IDE". If your choice or use of an IDE is causing problems, you don't understand what you are doing. The IDE isn't going to be there when the app runs in production, so it should be HELPING you, not an essential part of the component being built and tested.

and thus, related to that:

2. " "WebContent\\WEB-INF\\lib\\english-bidirectional-distsim.tagger"

DOS filenames in Java programs are never a good idea, if for no other reason than that one misplaced backslash can wreak havoc. Even if it's a DOS (Windows) file, use the Unix-style paths. Furthermore, you've included part of your Eclipse project in what I'm presuming to be your web application code. To properly locate a WAR resource, the path format should look more like this:

"/WEB-INF/lib/english-bidirectional-distsim.tagger"

Meaning folder WEB-INF at the top of the WAR.

That's above and beyond the questionable practice of putting something in /WEB-INF/lib that isn't a libary (jar).

A servlet's classpath includes the resources (class files, property files, and so forth) under /WEB-INF/classes. the contents of al jars found in the /WEB-INF/lib directory (note that this is different from command-line java, where a directory full of jars will not go into the classpath), followed by a run down the server-wide classpath (directories such as Tomcat's /lib directory). In most cases, you want your class-loadable resources to be contained within the WAR (/WEB-INF/classes and lib), not in the server library, with the exception of server-sharable resources such as jdbc drivers (if you don't know it's sharable, assume it isn't).

Classpath Additions from outside the server entirely, such as CLASSPATH environment or java command-line classpath are done at your own peril, and in some cases, the web application server will simply not even see them, since the webapp server has extensive classpath customization logic of its own.
 
Ahmed Faisal
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim Holloway wrote:My vision is a bit blurry today and I can't follow all that, but two things ring alarm bells:

1. Any question that starts with "I'm running XXX with YYY IDE". If your choice or use of an IDE is causing problems, you don't understand what you are doing. The IDE isn't going to be there when the app runs in production, so it should be HELPING you, not an essential part of the component being built and tested.

and thus, related to that:

2. " "WebContent\\WEB-INF\\lib\\english-bidirectional-distsim.tagger"

DOS filenames in Java programs are never a good idea, if for no other reason than that one misplaced backslash can wreak havoc. Even if it's a DOS (Windows) file, use the Unix-style paths. Furthermore, you've included part of your Eclipse project in what I'm presuming to be your web application code. To properly locate a WAR resource, the path format should look more like this:

"/WEB-INF/lib/english-bidirectional-distsim.tagger"

Meaning folder WEB-INF at the top of the WAR.

That's above and beyond the questionable practice of putting something in /WEB-INF/lib that isn't a libary (jar).

A servlet's classpath includes the resources (class files, property files, and so forth) under /WEB-INF/classes. the contents of al jars found in the /WEB-INF/lib directory (note that this is different from command-line java, where a directory full of jars will not go into the classpath), followed by a run down the server-wide classpath (directories such as Tomcat's /lib directory). In most cases, you want your class-loadable resources to be contained within the WAR (/WEB-INF/classes and lib), not in the server library, with the exception of server-sharable resources such as jdbc drivers (if you don't know it's sharable, assume it isn't).

Classpath Additions from outside the server entirely, such as CLASSPATH environment or java command-line classpath are done at your own peril, and in some cases, the web application server will simply not even see them, since the webapp server has extensive classpath customization logic of its own.



Thanks for your suggestions.

Following your lead, I put .tagger and .props files in "/WEB-INF/classes" folder and my project's folder structure is as follows:


Now I initialized tagger using following statement as you directed:


But unfortunately, the stack trace is same as before:

 
Stefan Evans
Bartender
Posts: 1836
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, this bit worries me:

You said that you changed the code to:



And you are getting the error message:
>Caused by: java.io.IOException: Unable to resolve "WebContent\WEB-INF\lib\english-left3words-distsim.tagger" as either class path, filename or URL



Not only is it a completely different path (starting from WebContent) it is a completely different file!
Are you sure that this bit of code is producing that message, or is that error coming from something else?
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!