Technical details of serve modules without publishing in Eclipse WTP and Tomcat? - eclipse

Eclipse's Web Tools Platform (WTP) allows you to configure Tomcat to "Server modules without publishing":
Web content will be served directly from the "WebContent" folder of the Dynamic Web Project. A customized context is used to make the project's dependencies available in the Web application's classloader.
In a 5 step process (just joking, you pick the # of steps), what happens technically and where are the files that Eclipse generates? I did notice that Eclipse generated a org.eclipse.jst.server.tomcat.runtime.70.loader.jar file in the Tomcat lib directory.

The idea is to serve a web application directly from the scattered directory structure of the development workspace, without packaging modules into JARs which then end up in WEB-INF/lib in a WAR.
The main benefits are:
You don't need to build archives.
When you change a resource in your workspace, the change is reflected in the running webapp without redeploying the webapp or restarting the server.
With Servlet 3.0, web resources may also be bundled in library JARs in META-INF/resources, so classes and resources may come from multiple workspace directories.
Tomcat 7.0 supports a VirtualWebappLoader and a VirtualDirContext to configure a web application based on a collection of scattered resource and class directories.
To serve your web app directly from your Eclipse workspace, WTP generates a suitable Tomcat configuration matching your project structure
in $WORKSPACE/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/conf/server.xml
For some reason, WTP does not directly use the Tomcat loader and context implementations but has its own WtpDirContext and WtpWebappLoader which are slightly different but similar. (I believe this approach is older than the current solution in Tomcat. There is some special logic for TLD scanning - I'm not sure if this is still required with the latest Tomcat versions.) These helper classes are contained in the org.eclipse.jst.server.tomcat.runtime.70.loader.jar you noticed.
Without Serve modules without publishing, when you change a web resource in META-INF/resources in a library module, this change will not be directly visible in the running application after reloading the current page in the browser.

Related

Can't I use subfolders in WEB-INF/lib?

I'm doing some clean-ups in a GWT (no maven) project. It has a lot of jars added in WEB-INF/lib. I know the purpose of those jars (for example for REST service - luckily it's documented) so I wanted to put them in appropriate subfolders for nicer look.
After re-adding them to build path (as now they are in subfolders) I tried to run SuperDevMode and got multiple warnings:
Server class 'X' could not be found in the web app, but was found on the system classpath
and some errors like:
Cannot find a default implementation of the HK2 ServiceLocatorGenerator
When I put those jars back in WEB-INF/lib (without subfolders) and re-add to build path everything runs just fine.
My question is: can't/should't I use subfolders in WEB-INF/lib? If so, why?
Server class loader is programmed to look only into WEB-INF/lib, not other folder nor subfolders.
I strongly suggest to get into the maven world, it has a steep learning curve but it will assure to your project a solid foundation to grow on. Another big plus of Maven is that it can automatically pick up the latest security patch of your libraries (Equifax, anyone?).
Extract from the Apache Tomcat 7 Docs:
WebappX — A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.

Eclipse virtual application deploy Vs ear deploy

I have a Java EE web application written in Eclipse and deployed on WebLogic.
When I deploy it from Eclipse (as a virtual application) it works fine. When I try to create an EAR file and deploy it from the WebLogic console I get a ClassNotFoundException.
What could be the reason?
How can I create an EAR file that will match the structure of the virtual application so it will work?
Usually this means a dependent library is not being deployed. This tends to be where Eclipse has a dependency which it fulfills as part of the internal build. When building it yourself, work out which libraries you need, and which are part of your application, and which are part of WebLogic. For your own libraries (ie those in the lib folders, or those that SHOULD be in the lib folder) make sure they are on the classpath. For external libraries, ie those WebLogic fulfills, make sure you have the appropriate schema descriptors setup to tell weblogic which libraries it needs to deploy with your application (typically things like JSF).
If you want proper control over the build, take a look at things like Ant. You basically tell it via xml what is needed, put it together, and it generates the Ear/Jar file for you (the Ear file containing all the dependencies as well, and/or with your descriptors for weblogic built in libraries).
If you are planning many builds, I find Ant useful once setup (you can tie it in with other programs too, so it can push a build to your Source Control Server as a tag, build documentation, etc). Ant can be a pain though- you need build descriptors for each library you need to build, as well as the Ear file.

How to deploy generated resources to tomcat with m2e-wtp?

I am pulling JavaScript from a jar as part of my build process. I wish this js to be part of my web resources for the app deployed on tomcat and I have updated my build process to allow this to happen. Doing a maven build (outside eclipse) works as expected and I can package up a war with everything in its proper order.
However, when building with eclipse I have run into some headaches. My understanding was in order to have web resources deployed to tomcat through an incremental build, I needed to put these build-time generated js files into the target/m2e-wtp/web-resources directory. However, when I publish these new files are ignored and the web-resources deployed to tomcat seem to be pulled from my source.
I also adjusted my project's deployment assembly settings. Through this I still don't have it working. I have the entry [source:/target/m2e-wtp/web-resources, DeployPath:/] which should find the newly generated files when I perform a "publish" to the server. However, the same thing happens where m2e-wtp seems to be pulling from source.
Am I missing something? How can I get standard behavior from m2e-wtp (i.e. make it comparable to a build done outside of eclipse)? Or can I have eclipse just build the war and deploy it as such (not do the incremental builds, I can sacrifice some speed)?
FYI (versions):
eclipse: (Using Spring Tool Suite) 3.2.0
m2e: 1.3.1
m2e-wtp: 0.17.0
tomcat: 7.0
Experiment added later:
After deleting my target dir, I performed a publish to Tomcat and all the web-resources were copied from my source. I also got a popup about files not found, most of which are compiled classes. However, it was looking for three files in the /target/m2e-wtp/web-resources/META-INF. Does the m2e-wtp plugin only look for specific files in a folder rather than the entire specified folder?
The problem is that the target directory was not being refreshed. Eclipse (or m2e plugin for that matter) doesn't recognize or care that files change in the target directory during a build, something that I was assuming. For now I have the auto-refresh (for the workspace) option on. The refresh on access option didn't working as it seemed to trigger the refresh only when I was publishing to tomcat for the first time.

How to set up JRebel in a Tomcat environment

I'm having a hard time getting JRebel to work in my current development environment.
I have multi module maven projects. Currently, the Tomcat instance is controlled via service (tomcat monitor) and the deployed web apps are configured with a XML located at ${catalina.home}/conf/Catalina/localhost where the docBase attribute points ${absolute maven project path}/target/app (and the attribute reloadable is true). So every time I do a maven build I only have to manually restart tomcat if there any classes changed. If the modifications occurred in the static resources (JSP, HTML, JS,
etc..) a page refresh will do it.
On my first attempt, I configured the web apps to run on a tomcat server running inside Eclipse. The maven plugin provided was also configured with success: all my sub-modules inherited the plugin configuration and I can saw in the tomcat startup the output messages from JRebel indicating the absolute project paths that were been listen. The only problem is that Eclipse WTP / Tomcat plugins don't go weel with War overlay feature in eclipse. After starting the server, only the resources present in the last web app (the module that have other War as dependencies) were deployed.
So, I returned to my original configuration development and introduced JRebel to it. I passed the JRebel java options to the Tomcat Vm, all maven modules had the rebel.xml (listening to the correct resource folders), but nothing happens. I can't see the usual JRebel messages and I experimented changing a JSP in the source folder and do a page refresh but the file ins't automatically redeployed (in this case a simple copy from the source folder the the ${maven.projec}/target/app will do the trick).
My two questions are:
It's possible to over come that eclipse WTP issue?
What is a funcional development environment involving maven eclipse and a external tomcat?
Any help would be much appreciated!
UPDATE 1
So, I got it. Kind of...I'm still struggling with the war modules overlaying. I have a main web app module that depends on several webapps modules. Because the rebel.xml it's generated dynamically via jrebel maven plugin when the main webapp build occurs, only the it's jrebel.xml prevail. All the other are squashed. The rebel.xml for the jars modules are at the right places (inside the jar file).
I can get it work if I create a custom rebel.xml for the main webapp that points to all the absolute directories containing the source files (static files such as JSP, HTML, JS, CSS, images, etc.) of the depending web apps. But this is worthless for my team development environments. I'm using maven properties but we've have two different maven multi-module hierarchy that don't know about each other and I can't use a root pom to connect them. So these kind of properties will not be enough to guarantee that the absolute paths generated on each developer machine in the rebel.xml are correct.
For now, I'm trying to tackle using some kind of maven plugin to do the rebel.xml merge. For the record without success yet.
This is becoming another issue a bit different of the original question :) Maybe I should through another question.
UPDATE 2
I got it working!..finally.
I used the XSLT Generator Maven Plugin to help me merge the various rebel.xml files. Also had to use the fabulous Maven Copy Plugin because the xslt transformation occurred after the final war packaging and I had to add the resulting rebel.xml to that WAR.
If someone needs the configuration files details down't hesitate asking.
Hope's this helps someone out there.
I got it working!..finally. I used the XSLT Generator Maven Plugin to help me merge the various rebel.xml files. Also had to use the fabulous Maven Copy Plugin because the xslt transformation occurred after the final war packaging and I had to add the resulting rebel.xml to that WAR.

Custom Re deployments from My Eclipse IDE

Experts
When we redeploy any application from an IDE such as MYEclipse , it just redeploys the .class files. I want to customize the eclipse developer, so the deployer can also deploy the custom files (other than class files).
Should i write any custom ANT script for Myeclipse or any custom settings the My Eclipse provides us ?
IDEs along the classes and libraries usually deploy everything they find in the web / www-root folder (in the folder that contains the WEB-INF and META-INF).
So you can configure your deployed applications structure using the IDE by structuring the content of that folder.
If it still doesn't fit your needs, then ANT would be the best option.
In my opinion ANT is always the best option, but using the development environment's functionality is proven faster then writing an ant build file.
Say, if you're developing a web service, a web application consuming that service, and a library that both the service and the webapp uses, then with a single (and not even long or difficult) ant file you can build them, create the aar, war and jar files and deploy them all in their correct places, eg. under axis, inside the global lib folder, and in the webapps folder.
All these in one step.