I'm working with some very old, monolithic software that is basically a heavily customized JBoss deployment. Unfortunately, this means that JBoss can't be started from the "Servers" view in Eclipse, it must be started as a Windows service or via the command line. There are multiple WARs/EARs, but the WAR classloaders are rarely used and most of the actual class files are located in jboss/shared/lib as .jars.
We need a way to run a Maven build in Eclipse (via m2e) and deploy the class files in the resulting .jar to C:/product/jboss/shared/lib so that when we start JBoss, we can use Eclipse to debug (as a remote java application). Ideally, the artifact that Maven pushes will not overwrite the existing .jar file that was originally installed. For example, if the Maven project builds an artifact named myjar-1.0.0.jar, we need a way to deploy the classes inside of myjar-1.0.0.jar to C:/product/jboss/shared/lib/classes so that they are picked up by the classloader prior to C:/product/jboss/shared/lib/myjar-1.0.0.jar, which was installed with the product.
Currently, our (very hacky) solution is this:
Under the project configuration's Java Build Path > Source tab, we use the "symlink" functionality under Advanced to map the Default Output Directory (e.g. project/target/classes) to a class folder (e.g. C:/product/jboss/shared/lib/classFolder). This modifies the .project file, which is checked into source control.
We build the project normally with a m2e launcher (e.g. clean install).
Assuming the Maven build is successful, we run an Eclipse project build. This pushes the class files to C:/product/jboss/shared/lib/classFolder:
We restart JBoss. Since classFolders take precedence over jars, JBoss will load the classes in C:/product/jboss/shared/lib/classFolder, which are identical to the classes in our Eclipse workspace.
We attach to JBoss and debug the project as a remote java application.
Pros:
We're able to push our new classes to JBoss and test them without backing up the original jars and copy/pasting the new ones by hand (jar hell).
Cons:
We're compiling twice -- once with the maven-compiler-plugin, and
once with an Eclipse project build (Java Builder).
The symlink functionality is hit or miss in my experience. Sometimes we need to
do the refresh project/close project/build project dance to get it to
work.
Is there a better way to do this? I cannot force them to restructure the project so heavily that all deployables are container-agnostic WARs, but our developers need to be able to make changes and quickly test them without manually copy/pasting .jars.
How old is old?
Have you looked at the Cargo plugin?
http://cargo.codehaus.org/Quick+start
It can deploy to JBoss 3.x.
It has a Java API so you should be able to write something to extend it to do what you want.
Why are you trying to deploying classes instead of jar files?
You can still remote debug via Eclipse with jar files.
Worst case scenario - use Ant.
Maven is not designed for this kind of stuff, trying to force it to work will just cause you pain.
Once you have got Maven generated the right artifacts, work out what you would do manually and then script it via Ant.
I would try looking at the maven-dependency-plugin which has the possibility of copying artifacts to different location.
Please check your Deployment Assembly (project -> properties -> Deployment Assembly) and verify if your maven libs are there.
Related
My project generates a Jar as the output package and uses an external War file, available on our Artifactory, as the Web Application to be deployed on Tomcat (currently using version 7). This War file contains all libs and modules required for the application to run.
I have already packaged and ran those projects outside eclipse on a "vanilla" Tomcat installation. In this scenario, the Jar my project generates is loaded on the context.xml file this way:
<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="/home/igor/workspace/myapp/myapp-2.4.3.jar"/>
Is there a way I can deploy this project on Tomcat using Eclipse and still be able to debug it? Can I use the Jar generated for this purpose or do I have to deploy the workspace project?
As for the War file, do (or can) I have to add it as an dependency?
Thanks in advance!
EDIT
We actually provide an Web Framework, which is packaged as a war. Other applications that use that framework are exported as jars and loaded into the framework through the context file as cited above.
Your question is confusing probably because of your custom plugin/classloader and deployment which is sort of orthogonal to debugging.
What I recommend is you keep whatever system you have to build/package/deploy and use JVM remote debugging. That is do not use the Eclipse WTP since you seem to have custom steps for deployment but rather build your code deploy & run a separate Tomcat instance and then run the remote debugger in Eclipse.
You will get some hotcode swapping with this method but not as much as something like JRebel.. (which you could use also) it will certainly be better than constantly redeploying.
I have my main web application(has its own POM) that is dependent on module A((has its own POM).
When i make a build using mvn install on web application, it dependent modules
are also built in to jar file and ultimately included under WEB-INF/lib folder of main web app.
But that does not happen in when i make build using eclipse kepler (containing both maven projects i.e main web app and its dependent module A).
When building with eclipse, it just put the modified classes under moduleA/target/classes/ folder but does not make any updated jar file and put it
under WEB-INF/lib folder of main web app.
Is there a setting where i can configure eclipse building the project same way as maven does (which will really save lot of time and help in hot deployment) ?.
It used to work in one of my projects looks like some configuration is required for this.
looks like m2e connector(i have SonarQube) needs some configuration to make eclipse build in the same fashion as maven build
When i do the project > right click > mvn install , i am able to make jar file.
But what i want is eclipse build automatically option do
the build for project/module wherever modification is done , construct the jar and include it in parent WEB-INF/lib folder if it is dependent module ?
Assuming you're using the Java EE flavour of Eclipse, you can easily deploy Maven based web applications to a local server (like Tomcat, Wildfly...) from the server view.
m2e-wtp, included in recent Eclipse Java EE distros, takes care of configuring all Eclipse settings based on your project pom.xml configuration and dependencies.
See this screencast to see how simple it is : https://www.youtube.com/watch?v=TksoKkSP208
For the record, deployment/publishing is performed by each server adapter differently. They're responsible for publishing the proper jars under the WEB-INF/lib folder of the deployed application. Dependent jar projects are automatically zipped and deployed to WEB-INF/lib without user interaction
I am working on a fairly big project that uses maven for dependency management. As part of this we are using Maven profiles to build and replace certain properties files that differ between test/dev/production environments.
To perform a build I would execute a Maven:build using the correct profile and mavens reactor would then build the projects in the correct order and store the jars in the .m2 folder, eg the domain jar first, then the service jar (with the domain jar included in its jar as a dependency) etc. This leads to a war file eventually with all the correct libs required by the war to run.
When eclipse performs its default build that it performs everytime you save a file the jars are not built with any profile, just a regular build.
When I then push the final war file to the server and it is exploded when the server starts up (started and deployed through eclipse) I get in the lib folder all the jars that maven had packaged into the war file but also all the jars that eclipse had built.
eg
lib/
domain.jar (built by eclipse)
domain.SNAPSHOT.1.0.jar (built by maven)
etc
Is there any way to prevent this from happening? This has the end consequence of there being two of every property file and only the order in which they are loaded determines which is used. A real hassle as different properties are used in different environments.
I found a slightly hacky solution to this problem.
In the web projects properties -> Deployment Assembly I modified the path for the offending jar files eg domain.jar from
WEB-INF/lib/domain.jar
to
WEB-INF/autogen/domain.jar
This leads to the eclipse generated jar files (with the wrong properties files) to be deployed to a folder that won't be loaded when tomcat starts. Not a perfect solution but it allows all the nice things of eclipse auto-building like code completion and error messages in the web project if the interface of the domain changes etc while also providing the correct profile when deployed.
Leaving this here for anyone else in this situation.
I have an eclipse Tomcat project that has several dependencies on other eclipse projects.
For example imagine the main project is called server and has several dependencies:
server
(depends on):
data-lib
server-utils
messaging-utils
Currently every time I change data-lib,server-utils,messaging-utils I have to recreate the .jar file and copy it into WEB-INF/lib directory of server. At that point I export the server as a .war and deploy to my server.
I want to make this process work from the cmd line using ant (note I know maven is out there but I know ant pretty well from past experience so would prefer sticking to it for now). Its easy enough to create the build file for server -- it will end up creating a .war file. But I want it to automatically build the dependent libs. I want to do this while preserving my development workspace in Eclipse.
What is the easiest and cleanest way to do this? Currently my thought is each individual project will have its own build.xml (i.e. data-lib/build.xml , server-utils/build.xml , etc). I will have the server/build.xml do an antcall to these individual build files and then copy the jars to the server/WEB-INF/lib directory.
Is there an easier/better way?
if you want an Ant based script, I would go with Apache Ivy. The basic idea is that each of your submodule has its own build.xml file and publishes (via Ivy) their "publications" (like a Jar file) to a repository on the file system. The other modules then import these "publications" to build the final product.
I am not sure if it can help you, but in your WAR project, right-click on it in Package Explorer, and click on Properties.
There is a "J2EE Module Dependencies". In this option, select all of the dependencies (i.e. "data-lib", "server-utils" and "messaging-utils").
Now, when you modify a Java class in one of the dependencies, Eclipse will recreate the JAR file and deploy it directly in the WEB-INF/lib of your web application.
So I started with a web services project (just a dynamic web project) that builds and debugs correctly from eclipse. We've pulled a chunk of common code out that we want to put into a shared library so now those classes are going into a separate jar project that the web project references.
On the web project, I did Project->Properties->Java Build Path->Projects->Add and added the jar project. And this correctly solved all the compile-time classpath problems and everything builds fine. But at runtime, when the tomcat server fires up, spring attempts to inject some of the classes contained in the jar file and I get a NoClassDefFoundError.
My .class and properties files and the contents of my META-INF directory are showing up in the ./build directory, but my WEB-INF/lib directory seems to be referenced in-place, and the jar dependency doesn't get copied in to it to show up as part of the Web App Library.
What is the magical incantation to tell eclipse that the other jar project needs to be available to tomcat at runtime? From our ant build script, we first just build the other project into WEB-INF/lib and everything works fine, but not for eclipse debugging.
I figured this out after spending some time on it. If you are in Eclipse Helios , go to properties > deployment assembly > add > project and select the dependent project you wish to add.
Java EE module dependencies would solve this problem.
You have already done the task of extracting your common classes into its own project, possibly because other projects depend on these classes. Either way, you'll have to ensure that this is a Utility project (appears under Java EE in the project wizards), and not just a plain Java project.
One that is done, you can proceed to add the Utility project to your build path (compile-time path) as you have figured out.
The additional (final) step is to establish a Java EE module dependency between your Dynamic Web project and the shared library, which causes the utility's classes to be placed in WEB-INF\lib during deployment, and even during export of the WAR. To do so, visit the dynamic web project's properties, and browse to the Java EE module dependencies. Ensure that your utility project is selected here. Redeploy/publish your application and you should be good to go.