When using a Eclipse 3.7 Indigo for Java EE Developers, there is something called Deployment Assembly . I could find on google and understood that it is similar to the J2EE Module dependencies where in we could select the jar and which goes and sits in the EAR folder or in WEB-INF/lib in case of WAR. Now the doubt I have is,
I have a JavaProject Dependencies. I have added all the dependent Jars via classpath variable. Now the Dependencies Project is added as dependency to my Web Project TestWebProject. The compilation of the Web Project is correct but during runtime I get an error because some jar was not found. I could fix this my include jar in Deployment Assembly of Dependencies Project, which is a standalone project.
The question is that, why I had to fix the jar in deployment assembly since ,first, its a standalone project and second is if I would not have this deployment assembly , how could this be fixed?
I could find on google and understood that it is similar to the J2EE Module dependencies
It was called "J2EE Module Dependencies" until with Eclipse 3.5. After that version, it was renamed to "Deployment Assembly". But it's effectively the same in case of Java EE web projects.
The question is that, why I had to fix the jar in deployment assembly since its a standalone project
Because this way Eclipse will autobuild a JAR file of the project and put in /WEB-INF/lib of the web project's deployment. If you don't do that, the JAR isn't available during webapp's runtime, but only during compiletime and Eclipse expects that you've already built and placed it anywhere else in runtime classpath, e.g. server's own /lib.
if I would not have this deployment assembly , how could this be fixed?
Manually build/export the JAR and drop in webapp's own /WEB-INF/lib or server's own /lib. The "Deployment Assembly" configuration is however more easy and the recommended way.
See also:
Business Logic Layerin Servlet and JSP
When assembling a WAR, Eclipse cannot tell just by looking at your build path dependencies whether they are something that should be bundled in WAR's WEB-INF/lib directory or if they are something that you expect to be available on your server classpath. Extra metadata is needed to differentiate among those cases.
If you look in your problems view, you should see numerous warnings that look like this:
"Classpath entry [something] will not be exported or published..."
Right click on these and select "Quick Fix". You will see a dialog with available fixes. One of them is going to say something like "Mark the associated classpath entry as publish/export dependency...". Use that option.
The above will make a slight alteration to your Java project's .classpath file to tag the dependencies for inclusion in the assembly. You can test without running by exporting a WAR file and checking the contents of WEB-INF/lib folder.
Build path - place your jar's here directly, it will be available for code runtime and compile time.
Deployment assembly - eclipse expects the projects under this path to be bundled and deployed as .jar in web-inf/lib folder. So that it is available for both compile time and run time. If the project is not deployed in deployment assembly then the code is available only for compile time, eclipse won't bundle it and at run-time dependent projects are unavailable to the code.
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
Are .classpath and .project files as created by Eclipse, only used by Eclipse internally? Are these files being used by JDK? How do Java EE application servers find classes and path?
In between, when I create the ear, war using ant, I will use ant options to look out for the libraries for the project compilation.
Then does the application server use .classpath for compilation?
Java EE application servers don't need the classpath which we set in Eclipse for the war (web project) to run because while packaging the war, we stuff all the required jar's in the lib folder of the war file. When the application server starts , it loads all the jars from the lib folder without the need for any classpath declaration.
Also, in case any external dependencies are needed, most Java EE servers provide facility to define external jar dependencies.
And yes, .project, .settings folder etc. are all needed by Eclipse to handle the classpath and other settings of your workspace.
if we put it simply
.classpath and .project are eclipse metadata files and are used by eclipse only. They are meaning less for other applications.
I have a java web project in eclipse and want to define a tomcat server.
It seems that in the tomcat server I must define again my classpath. How can I tell tomcat to just use the classpath from my project (shouldn't this be obvious?).
Unfortunately my jars are scattered all around and it is an headache to add them one by one to my tomcat configuration and maintain this.
Here you go :
Run -> Run Configurations... -> Classpath
You don't have to tell tomcat to look for jars scattered all around the places. This can be easily taken care by eclipse. Configure your eclipse build path properly. Create Libraries (in eclipse) and group jar together. Try to export the war and check if eclipse is packaging all the required jars in WEB-INF/lib.
No, Tomcat and web apps have a pretty well-defined CLASSPATH. You shouldn't have to specify anything if you package your app properly:
All the packages and .class files in WEB-INF/classes are in CLASSPATH.
So are all the JARs in WEB-INF/lib
You should figure out how to put your JARs in the right place - that's WEB-INF/lib of your WAR file. Maybe Ant or Maven can help you.
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.