I am using eclipse and added tomcat 6 server. whenever i try to start the server it automatically copies the server api jar into the WEBINF/lib folder and the app does not start
INFO: validateJarFile(/media/01CB9CAC704E03A0/Projects/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/myapp/WEB-INF/lib/servlet-api-2.5.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
I got the same problem and finally got it to work after looking at this among other pages. I am going to list it here in case other people run into the same issue.
In my case, the myeclipse project was created from a maven .pom file which lists the JEE 1.5 files as "provided" scope i.e. these files will be provided by the container (in my case tomcat 6). So if I create a war file using maven and drop it in the webapps dir it just works fine. It gets a little tedious doing that every time you make a change, so I decided to go for exploded deployment and thats when I ran into the same issue.
Since the project file was created from the pom file, these dependencies came in but Eclipse project file does not recognise these as "provided" and not to be deployed. And TOMCAT is not happy when it finds two implementations of the spec:
"Servlet spec 2.3 sec 9.7.2 recommends … The classloader that a container uses to load a servlet in a WAR must allow the developer to load any resources contained in library JARs within the WAR following normal J2SE semantics using getResource. It must not allow the WAR to override J2SE or Java servlet API classes. It is further recommended that the loader not allow servlets in the WAR access to the web container’s implementation classes. It is recommended also that the application class loader be implemented so that classes and resources packaged within the WAR are loaded in preference to classes and resources residing in container-wide library JARs."
I toyed with the above solution to change my deplyment assembly config but that is not helpful alone since these jars get bundled in if I select the "JARS from the build path"
in the menu project properties/MyEclipse/Web/Deplyment/Configure workspace settings.
And I need to do that cos I have other dependencies jars (not provided by container).
Solution:
I removed these jars from the dependencies in the build path manually.
Instead I added a dependency on User Library - JAVA EE5.
And in the deployment configuration I removed the option of JARS exported from User Libraries of required projects.
YMMV. But in any case if you read the servlet spec definition above and then look at the config in your workspace, you can sort it out.
Hope this helps.
Go to your project properties and look under Deployment Assembly page. This page describes how your app will be packaged for deployment or export. Take a look at entries regarding libraries. You have to figure out which of those entries points to the servlet api jar and remove it. If the entry points to other jars that do need to be packaged, you will need to split it into several separate build path entries, so you can tell Eclipse exactly what does and does not need to be packaged.
Related
How should I add JAR libraries to a WAR project in Eclipse without facing java.lang.ClassNotFoundException or java.lang.NoClassDefFoundError?
The CLASSPATH environment variable does not seem to work. In some cases we add JAR files to the Build Path property of Eclipse project to make the code compile. We sometimes need to put JAR files inside /WEB-INF/lib folder of the Java EE web application to make the code to run on classes inside that JAR.
I do not exactly understand why CLASSPATH does not work and in which cases we should add JARs to Build Path and when exactly those JARs should be placed in /WEB-INF/lib.
The CLASSPATH environment variable is only used by the java.exe command and even then only when the command is invoked without any of the -cp, -classpath, -jar arguments. The CLASSPATH environment variable is ignored by IDEs like Eclipse, Netbeans and IDEA. See also java.lang.ClassNotFoundException in spite of using CLASSPATH environment variable.
The Build Path is only for libraries which are required to get the project's code to compile. Manually placing JAR in /WEB-INF/lib, or setting the Deployment Assembly, or letting an external build system like Maven place the <dependency> as JAR in /WEB-INF/lib of produced WAR during the build, is only for libraries which are required to get the code to deploy and run on the target environment too. Do note that you're not supposed to create subfolders in /WEB-INF/lib. The JARs have to be placed in the root.
Some libraries are already provided by the target JEE server or servletcontainer, such as JSP, Servlet, EL, etc. So you do not need put JARs of those libraries in /WEB-INF/lib. Moreover, it would only cause classloading trouble. It's sufficient to (indirectly) specify them in Build Path only. In Eclipse, you normally do that by setting the Targeted Runtime accordingly. It will automatically end up in Build Path. You do not need to manually add them to Build Path. See also How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
Other libraries, usually 3rd party ones like Apache Commons, JDBC drivers and JEE libraries which are not provided by the target servletcontainer (e.g. Tomcat doesn't support many JEE libraries out the box such as JSF, JSTL, CDI, JPA, EJB, etc), need to end up in /WEB-INF/lib. You can just copy and paste the physical JAR files in there. You do not necessarily need to specify it in Build Path. Only perhaps when you already have it as User Library, but you should then use Deployment assembly setting for this instead. See also ClassNotFoundException when using User Libraries in Eclipse build path.
In case you're using Maven, then you need to make absolutely sure that you mark libraries as <scope>provided</scope> if those are already provided by the target runtime, such as JEE, Servlet, EL, etc in case you deploy to WildFly, TomEE, etc. This way they won't end up in /WEB-INF/lib of produced WAR (and potentially cause conflicts with server-bundled libraries), but they will end up in Eclipse's Build Path (and get the project's code to compile). See also How to properly install and configure JSF libraries via Maven?
Those JARs in the build path are referenced for the build (compile) process only. If you export your Web Application they are not included in the final WAR (give it a try).
If you need the JARs at runtime you must place them in WEB-INF/lib or the server classpath. Placing your JARs in the server classpath does only make sense if several WARs share a common code base and have the need to access shared objects (e.g. a Singleton).
If you are using Maven:
Open the project properties, and under Deployment Assembly click Add...
Then select Java Build Path Entries and select Maven Dependencies
Resolved by setting permissions.
Had related issue using PySpark and Oracle jdbc. The error does not state that the file cannot be accessed, just that the class cannot be loaded.
So if anyone still struggles, check the permissions. Some might find it obvious tho'.
I want to give the answer for the folowing link question ClassNotFoundException oracle.jdbc.driver.OracleDriver only in servlet, using Eclipse
Ans: In Myeclipse go to Server-->left click on Myeclipse Tomcat7-->Configure Server Connector-->(Expand)Myeclipse Tomcat7--> Paths-->Prepend to classpath-->Add jar (add oracle14 jar)-->ok
How should I add JAR libraries to a WAR project in Eclipse without facing java.lang.ClassNotFoundException or java.lang.NoClassDefFoundError?
The CLASSPATH environment variable does not seem to work. In some cases we add JAR files to the Build Path property of Eclipse project to make the code compile. We sometimes need to put JAR files inside /WEB-INF/lib folder of the Java EE web application to make the code to run on classes inside that JAR.
I do not exactly understand why CLASSPATH does not work and in which cases we should add JARs to Build Path and when exactly those JARs should be placed in /WEB-INF/lib.
The CLASSPATH environment variable is only used by the java.exe command and even then only when the command is invoked without any of the -cp, -classpath, -jar arguments. The CLASSPATH environment variable is ignored by IDEs like Eclipse, Netbeans and IDEA. See also java.lang.ClassNotFoundException in spite of using CLASSPATH environment variable.
The Build Path is only for libraries which are required to get the project's code to compile. Manually placing JAR in /WEB-INF/lib, or setting the Deployment Assembly, or letting an external build system like Maven place the <dependency> as JAR in /WEB-INF/lib of produced WAR during the build, is only for libraries which are required to get the code to deploy and run on the target environment too. Do note that you're not supposed to create subfolders in /WEB-INF/lib. The JARs have to be placed in the root.
Some libraries are already provided by the target JEE server or servletcontainer, such as JSP, Servlet, EL, etc. So you do not need put JARs of those libraries in /WEB-INF/lib. Moreover, it would only cause classloading trouble. It's sufficient to (indirectly) specify them in Build Path only. In Eclipse, you normally do that by setting the Targeted Runtime accordingly. It will automatically end up in Build Path. You do not need to manually add them to Build Path. See also How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
Other libraries, usually 3rd party ones like Apache Commons, JDBC drivers and JEE libraries which are not provided by the target servletcontainer (e.g. Tomcat doesn't support many JEE libraries out the box such as JSF, JSTL, CDI, JPA, EJB, etc), need to end up in /WEB-INF/lib. You can just copy and paste the physical JAR files in there. You do not necessarily need to specify it in Build Path. Only perhaps when you already have it as User Library, but you should then use Deployment assembly setting for this instead. See also ClassNotFoundException when using User Libraries in Eclipse build path.
In case you're using Maven, then you need to make absolutely sure that you mark libraries as <scope>provided</scope> if those are already provided by the target runtime, such as JEE, Servlet, EL, etc in case you deploy to WildFly, TomEE, etc. This way they won't end up in /WEB-INF/lib of produced WAR (and potentially cause conflicts with server-bundled libraries), but they will end up in Eclipse's Build Path (and get the project's code to compile). See also How to properly install and configure JSF libraries via Maven?
Those JARs in the build path are referenced for the build (compile) process only. If you export your Web Application they are not included in the final WAR (give it a try).
If you need the JARs at runtime you must place them in WEB-INF/lib or the server classpath. Placing your JARs in the server classpath does only make sense if several WARs share a common code base and have the need to access shared objects (e.g. a Singleton).
If you are using Maven:
Open the project properties, and under Deployment Assembly click Add...
Then select Java Build Path Entries and select Maven Dependencies
Resolved by setting permissions.
Had related issue using PySpark and Oracle jdbc. The error does not state that the file cannot be accessed, just that the class cannot be loaded.
So if anyone still struggles, check the permissions. Some might find it obvious tho'.
I want to give the answer for the folowing link question ClassNotFoundException oracle.jdbc.driver.OracleDriver only in servlet, using Eclipse
Ans: In Myeclipse go to Server-->left click on Myeclipse Tomcat7-->Configure Server Connector-->(Expand)Myeclipse Tomcat7--> Paths-->Prepend to classpath-->Add jar (add oracle14 jar)-->ok
I have 4 referenced libraries on my Java Build path for my Java Project in MyEclipse Blue 10.7. My understanding is that one of the points of using referenced libraries was so that they are not included in the final war file when it is built and deployed. However, in my case all of the jars in these 4 referenced libraries are indeed being included in the lib folder in my final war file when it is built and deployed.
Is my assumption about how referenced libraries work wrong, or is there a setting or something to keep referenced library jars from being included in the war file?
Thank you for your time!
Your assumption is false. According to the The Java EE Tutorial, section 5.3 Packaging Web Archives the folder WEB-INF/lib
[...] contains JAR files that contain enterprise beans, and JAR archives of libraries called by server-side classes
The usual case is that a WAR file contains all referenced libraries but not the JEE libraries like the servlet API itself. JEE libraries are provided by the servlet container.
So each webapplication running in a servlet container can have its own version of a library.
I knew there had to be a setting in Eclipse to control exactly what was included in the lib folder and my colleague found this link that led to the answer; I'll post the details below for completeness. However, I should be clear that I'm using MyEclipse Blue 10.7...not just Eclipse. I'm going to edit my original post above stating such. I'm sure there is a similar setting in Eclipse somewhere however.
Go to Window >> Preferences >> MyEclipse >> Java Enterprise Project >> Web Project
Go to the Deployment Tab
Under Library Deployment Policies make sure that "Jars from User Libraries" is unchecked
That's it. Since that setting was checked the jars from my libraries were always being included in my lib folder in my war; in my case that was not the desired behavior.
Thanks to #vanje for getting me thinking with the comment thread above as well.
I have a two application webapp1 and webapp2. Both application use the same library zx.jar.
Now i have put the jar in two location /webapp1/ROOT/WEB-INF/lib and /webapp2/ROOT/WEB-INF/lib
But I don't want to load jar twice. I want to use the jar /tomcat/lib ?
How can I implement this in Linux environment?
Put your library at below location
•Tomcat 6 $CATALINA_HOME/lib
•Tomcat 5 $CATALINA_HOME/common/lib
More info Apache ClassLoader Howto.
Just put your jar in the in the tomcat lib folder ($CATALINA_HOME/lib).
And if you are using maven as build tool, just put <scope>provided</scope> in the dependency of the corresponding jar!
And if you are using Ant to build, just make sure that, you don't copy the jar to the deployed application's lib folder, while building and deploying your application.
With Tomcat 6, "common" JARs to be shared between multiple servlets should be placed in $CATALINA_BASE/lib or $CATALINA_HOME/lib. It is documented in the Apache 6 - Classloader HOW TO document.
However you need to be careful when you do this because:
"common" JARS and other files / directories in the lib directories take precedence over stuff in each webapp,
any static variables in "common" classes are actually visible to all webapps, and
leakage of types from one webapp to another can cause strange problems; e.g. type casts failing unexpectedly.
Summary
Classes from 3rd party jar files are accessible when added to build path while running a standalone JUnit test, but "ClassNotFoundException" when accessed through plain old java objects from within a dynamic web project.
IDE used: Eclipse
Web Server: Apache 7
Details
My project required a lot of 3rd party jars, namely sqlite, eclipse jdt & jsoup. I had created this project as a standalone project and all the classes from the jars were accessible fine.
But now I have copied the entire "src" folder into a "dynamic web project". I have created a folder "jars" which contains all these 3rd party jars and ensure that all of these are added to the build path by following these steps:
Project properties --> Java Build Path --> Libraries --> Add jars --> Select all the jar files from jars folder.
These jars are accessible fine when I run a standalone JUnit test inside the web project. Note that this junit test does not require a server by any means.
But when I try to "Run on Server.." , I keep on getting ClassNotFoundException like these for all the 3rd party classes:
java.lang.ClassNotFoundException: org.sqlite.JDBC
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1672)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1517)
I'm sure this has got to do something with my lack of knowledge of how applications are deployed on the web.
The runtime classpath can be different from the build classpath. Create an explicit launch configuration. The default will start with the build classpath but you may have to manually tweak it to include those 3rd party jars.
I've run into this problem before with Eclipse and the Web Server Tools project. Check your .settings files and other files for configuring the plugins that you're using with your project. You may have to remove some filters in the Eclipse view. WST constructs its build path differently, so it may not be using the jars that you've included in your project.
I figured it out. I just had to put all the jars in the WEB-INF/lib directory. I assumed that Eclipse would do all the required settings for me when I asked it to use the mentioned jars. But I guess there are somethings that are not automated very well.