Transitive project dependencies in Eclipse WTP - eclipse

I've created a bunch of projects in Eclipse 3.7.2. Let's give some of them a name:
W (a Dynamic Web Project)
A (some library)
B (a library with lots of common stuff, that is used by other projects too)
Project A depends on project B, so B is in A's build path. Project W depends on project A so I've added A as Deployment Assembly in W.
When I export a WAR from within Eclipse only the JAR file for A gets added to WEB-INF/lib. Eclipse shows the following warning:
Classpath entry /B will not be exported or published. Runtime
ClassNotFoundExceptions may result.
The warning is correct. I get a ClassNotFoundExceptions at runtime. Of course Eclipse provides a Quick fix for the warning which is "Mark the associated raw classpath entry as publish/export dependency". However, this doesn't fix my problem. B still doesn't get deployed with W.
I tried manually adding B as Deployment Assembly in A . That includes the B.jar within A.jar which isn't really what I want and I still get the ClassNotFoundExceptions.
The only thing that works is manually adding B as Deployment Assembly in W. Eclipse still shows the warning from above, but the runtime exceptions are gone.
Am I missing something or is this really the only way to get this working?

In order to make Eclipse's "Export / Web / WAR File" work, you have to make your project "b" to appear in the "Web App Libraries" container.
You can edit deployment configuration using Deployment Assembly page in the project properties and add your project "b" in there:
Alternatively, you can open configuration file at /w/.settings/org.eclipse.wst.common.component and add reference to project "b" manually:
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="w">
<wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
<dependent-module archiveName="a.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/a/a">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="b.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/b/b">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="context-root" value="w"/>
<property name="java-output-path" value="/w/build/classes"/>
</wb-module>
</project-modules>
Once it is done, you'll see project "b" in the "Web App Libraries" classpath container and export to WAR file will also add b.jar into WEB-INF/lib.

Related

How can I add a hidden folder during creation of a WAR file.

I am developing a dynamic web application and exporting the WAR file to deploy it on the Server. My project directory in Eclipse has a hidden folder named .svn which I want to include in the WAR file being generated.
For Example: I have ProjectName/.svn folder, which I want to include in WebContent/WEB-INF/classes folder during creation of the WAR file. Is there a way to do this in Eclipse?
I also don't understand the reason, but this is how you can do that:
If you have a dynamic web project, than you have a config file which is called .settings/org.eclipse.wst.common.component. If you add a line into it like below, you can instruct Eclipse to build other stuff into the WAR. Deploy path is the relative path inside the WAR, source path is a relative path inside your project. If you link an external folder into your project, you can even include that.
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="bla">
<wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
<!--your extra stuff is this line-->
<wb-resource deploy-path="/.svn" source-path="/.svn"/>
<property name="context-root" value="bla"/>
<property name="java-output-path" value="/bla/build/classes"/>
</wb-module>
</project-modules>
I did not try it, but it should work I guess.

Maven dependencies not deployed on Eclipse Tomcat instance

I'm using Spring Tool Suite 3.1 and I have some issues deploying a web application to tomcat.
When I hit "run on server" and the server starts it throws the famous:
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
So I check the /wtpwebapps directory to find that the project is deployed, but inside the lib folder only a few libraries are present. I completely miss the rationale behind their selection. Of course the libraries related to spring aren't there. Can anyone help?
This is my org.eclipse.wst.common.commonent file, maybe it can be useful:
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="Checkup">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/resources"/>
<property name="context-root" value="Checkup"/>
<property name="java-output-path" value="/Checkup/build/classes"/>
</wb-module>
EDIT:
you can see the list of maven plugin embedded with STS installation (no customizations)
add maven dependencies to deployment assembly, by right clicking project - navigating to deployment assembly, and then adding the maven dependencies library.
after hours of pain it seems the problem is solved thanks to magics or something. The "mysterious" procedure that fixed the things is the following:
run your project on tomcat and get the error
clean tomcat rclick ---> clean (not clean working directory) while your project is still on the server
run the server again
the tricky part is cleaning tomcat when the web app is still deployed. I really don't know why it works. If you stop the server, remove the application, clean the server and redeploy the application again you get the error.
I won't dare to understand further, I accept the mystery.
NimChimpsky's answer is right solution for me. Only it's not very specific. The detailed steps is: right click project -> select "properties" -> search "Deployment Assembly" -> click "Add" button -> add "Maven Dependent"
Another way to fix this issue is by using the terminal (Linux or Mac) or the command prompt (Windows). Navigate to the folder of the project and use the following command:
mvn eclipse:eclipse -Dwtpversion=2.0
Once the command is successfully executed, a new file called org.eclipse.wst.common.component will be created inside the .settings folder of the project.
Start the server and it should pick all the dependent libraries automatically.

Strange behavior of Eclipse WTP deployment of dependencies in Tomcat server

I have a strange behavior in the Tomcat deployment process made by my Eclipse WTP.
I am using Eclipse 3.7 (Indigo), WTP 3.3, no m2eclipse plugin, Java 1.6, Tomcat 5.5.
My application is a web application that have some other projects as dependencies, as well as some third-parties dependencies.
My project is managed by Maven, and everything works fine when we build the application using this tool.
To work on my project using Eclipse, I run mvn eclipse:clean eclipse:eclipse and then, I import my projects in the IDE.
My problem occurs when I want to deploy this web application on a Tomcat 5.5 server (this server is managed by Eclipse).
When I create a new Tomcat server, and deploy my my-project-portal application in it, it only adds the my-project-xxx dependencies, as well as few third-parties dependencies (about 9 of the hundreds defined).
On one of my colleagues desktop (he is using Eclipse 3.5), no third-parties dependency are deployed at all, just the my-project-xxx JAR...
However, when I look at the web-app project properties, in Java Build Path > Libraries, or in "Deployment Assembly", the list of dependencies is correct and complete.
Notes
I did some tests with an older Eclipse (3.3, with WTP 3.1) and I do not encounter any deployment issue.
However, this WTP was still using the "Java EE Modules Dependencies", which is not the case of the latest WTP version.
Until now, we used a custom Maven plugin after the mvn eclipse:eclipse that copies all the dependencies (including transitives ones) into my-webapp-project/WebContent/WEB-INF/lib.
Doing that, Eclipse automatically deployed the content of these dependencies, and thus, we got all the dependencies in the Tomcat server.
Questions
What is wrong with my process?
Do I really need to copy all the dependencies in the WEB-INF/lib directory?
What is the normal procedure when we want to deploy a web application on a Tomcat server, using Eclipse?
Here is an extract of my Eclipse configuration files after running mvn eclipse:eclipse:
.classpath
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/asm/asm/2.2.2/asm-2.2.2.jar" sourcepath="M2_REPO/asm/asm/2.2.2/asm-2.2.2-sources.jar"/>
<classpathentry kind="src" path="/my-project-business"/>
...
<classpathentry kind="output" path="WebContent/WEB-INF/classes"/>
</classpath>
.settings/org.eclipse.wst.common.component
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="my-project-portal">
<property name="context-root" value="my-project-portal"/>
<wb-resource deploy-path="/" source-path="/WebContent"/>
<property name="java-output-path" value="/WebContent/WEB-INF/classes"/>
<dependent-module deploy-path="/WEB-INF/lib" handle="module:/classpath/var/M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar">
<dependency-type>uses</dependency-type>
</dependent-module>
...
<dependent-module deploy-path="/WEB-INF/lib" handle="module:/resource/my-project-business/my-project-business">
<dependency-type>uses</dependency-type>
</dependent-module>
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/>
</wb-module>
</project-modules>
I think you have a misconfiguration problem because:
If your project is managed by maven, you will never need to set your '.classpath' with the dependencies needed by this tool, for example if you need one different library or change the version of one, you will need to update the configuration in your eclipse project, etc. Idem for your 'org.eclipse.wst.common.component' file.
I think you will need to install the WTP support for m2eclipse like #stivlo says, of course install the m2eclipse and review your project configuration, because you need to remove all the dependencies defined in those files.
Right now, I never copy all the dependencies in the /WEB-INF/lib directory, because I don't want to have to keep an eye on those directory. For example, when I need to start Tomcat, the m2eclipse plug-in deploys automatically all the libraries and differences (i.e static files, classes, resource files, etc) in the internal Eclipse directory related and that's it, the server starts with the context, with all the files needed. I'm always using the plugins related in Eclipse for convenience.

exclude some source files from being deployed to the container

I have a EJB project in Eclipse that contains two source folder "ejbModule" and "test"
where ejbModule contains source code for ejbs and test contains source code for the JUnit tests.
when I export the ear file using the right click -> export, I found the the .class files of the Junit tests are being exported within the EAR.
EDIT:
So, how I can prevent these source files from being deployed to the container, but in the same time I still need eclipse to consider them as source files??
(I am not asking the same question here: exclude files from jar or war in eclipse )
In eclipse 3.6 right click on the project, press properties. Then go to "deployment assembly" property page. There you can define, what are the parts of the project artifact.
Update:
On the other hand, the GUI of WTP do not support everything the builder can handle. Source folders can be easily excluded, if you edit the .settings/org.eclipse.wst.common.component file (both in 3.5 and 3.6 eclipse) in project root. It does look like this (example from one of my projects):
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="gui">
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp"/>
<dependent-module deploy-path="/WEB-INF/lib" handle="module:/resource/aoprules/aoprules">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module deploy-path="/WEB-INF/lib" handle="module:/resource/base/base">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="context-root" value="gui"/>
<property name="java-output-path" value="/gui/target/classes"/>
</wb-module>
</project-modules>
You simply remove the project-modules/wb-module/wb-resource element, which has the src/testas source-path attribute. Then refresh project.

Eclipse buildtime and runtime classpaths for easy execution of junit test cases

I've a large eclipse project with multiple junit classes. I'm trying to strike a balance between adding runtime resources to the eclipse project classpath, and the need to configure mutliple junit launch configurations.
I realise the default eclipse build classpath is inherited by all unit test configurations, but some of my tests require extra runtime resources. I could add these resources to the build classpath, but this does slow my overall project build time (since
it has to keep more files in synch). I don't like the idea of including * resources and jars on the runtime classpath.
The two options that i have are these, the positive and negative cases as i see it are listed
1 : Add all runtime resources to eclipse classpath.
POS I can select a unit test and run it without having to configure the test classpath.
POS Extra resources on build classpath means eclipse slows down.
NEG More difficult to ensure each test uses the correct resources.
2 : Configure the classpath of each unit test
POS I know exactly what resources are being used by a test.
POS Smaller build classpath means quicker build and execution by eclipse.
NEG Its a pain having to setup multiple separate junit runtime classpaths.
Ideally i'd like to configure one base junit runtime configuration, which takes the default eclipse build classpath, adds extra runtime jars and resources. This configuration could then be reused by the specific junit test cases, Is anything like this possible?
Looking at a specific junit launch configuration which can be exported to a share project file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
<stringAttribute key="bad_container_name" value="/CR-3089_5_1_branch."/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/CR-3089_5_1_branch/src/com/x/y/z/ParserJUnitTest.java"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.x.y.z.ParserJUnitTest"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="CR-3089_5_1_branch"/>
</launchConfiguration>
is it possible to extend/reuse this configuration, and parameterise the 'org.eclipse.jdt.launching.MAIN_TYPE' value?
I'm aware of the commons launch and jar manifest file solutions to configuring the classpath, but they both seem to assume that an ant build is run before the test can execute. I want to avoid any eclipse dependency on calling an ant target when
refactoting code and executing tests.
Basically - What is the the easiest way to seperate and maintain the eclipse buildtime classpath and junit runtime classpaths?
The first solution could be to separate completely the project from its unit tests:
one project for the current build
one project for JUnit tests (or several if different kind of classpath are involved): that project will have the first dev project in its dependencies, and will not have to specify the classpath from that development.
A cleaner way (because it would be used within Eclipse, but also outside Eclipse) would be to transform your project in a maven one, through m2eclipse for instance.
That way, maven can manage the dependency compositions of several projects in order to have the right classpath for the test task.