Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

"Everything should be made as simple as possible, but no simpler" (attributed to Albert Einstein) 

It may reasonably be said that Eclipse tries to make J2EE development simpler than is reasonably possible. Eclipse is almost successful, close enough so that it is quite usable as long as you realize what cannot possibly be made to work exactly right and solve that problem with another tool.

The Maven POM contains declarations that drive a Java compiler running under Maven to compile all the source, and then it builds JAR, WAR, and EAR files. The M2E support for Maven inside Eclipse tries to understand the POM file and to create a set of Eclipse project configurations that do exactly the same thing. Typically this works for the compile part, and therefore it works for all the good things that Eclipse does about autocomplete of source and autocorrect of errors.However, Eclipse is not really in the business of building actual , including Build Path references to dependent libraries in the Maven local repository, to compile the source in the same way. This part works, so Eclipse can be a good source editor including autocomplete hints and the ability to find the source of classes you are using or all references to a method you are coding.

It is in actually running and debugging the code that Eclipse goes one step too far. You can define application servers to Eclipse by referencing the directories in which you have installed versions of Tomcat or JBoss. However, Eclipse does not run these servers by starting them in the normal way, because Eclipse is not in the business of generating production artifacts like JAR, WAR, or EAR files. Instead, it Artifacts are what Maven builds. Eclipse compiles source and holds resource files in its workspace and it tries to do something "better". The problem you would have if you were doing simple Java WAR file development is that when you make a change to better than just generating a WAR file and deploying it to the server. The problem with a normal WAR deployment is that every time you edit an HTML or JSP file and press save, then the file is saved to the Eclipse workspace. However, even if the Web server you are using supports "hot deploy", getting this changed file over to the server would normally require a separate deploy step.

So Eclipse J2EE support was designed to "hack" all the standard Web application servers. It has special code for Tomcat or JBoss to "deploy" to the server a virtual EAR or WAR. There is no actual EAR or WAR file artifact. Instead, the server is run in a special mode with Eclipse configuration modifications that make it think there is an EAR or WAR directory, when in fact the directory is being simulated by Eclipse using the files in the Eclipse project in the workspace. So in this mode, when you save an HTML page to the workspace, you are logically, though not physically, also saving it to the virtual WAR in the server. Tomcat or JBoss see the file as having been updated, so they use the new version of the file just as if it had been hot deployed to their real webapp or deploy directory.

This is one hack too far for any really complicated application. The problem is that the hacked Tomcat or JBoss configuration is not the real Tomcat or JBoss configuration that would be run if the server ran normally, and the difference may be important if you have other configuration changes you need to make in order for your program to run correctly.

So , you have to recreate and redeploy the WAR. Eclipse wants to use the "hot deploy" capability of J2EE servers, where when you change an HTML, CSS, or JSP page the server notices the change and starts immediately using the new copy.

So instead of copying files over to the standard application server deploy directory, the Eclipse J2EE support has modules that "hack" the Web server to create what amounts to a virtual WAR or EAR. Code running in the hacked server pretends that there is a standard deployed artifact, but the ClassLoaders for this artifact obtain the actual classes and resource files directly from the Eclipse workspace instead of the JBoss deploy directory. Therefore, if you edit and save an HTML file in the Eclipse workspace, the application server sees the same file as changed in its application and switches to the new edited text.

The problem is that this modified application server configuration is not the real application server, so if your application depends on other changes that you make to the same server environment, or if you have any code that penetrates the "virtual directory" structure that Eclipse has created, then your application will not run correctly. It may be good enough for some early development work, but if you want to make small changes to an application that is already in production, you want a runtime that more accurately represents production. If that is not enough, Yale depends on last minute configuration changes made by the Installer project to the WAR file as it is being deployed to JBoss, and Yale applications will not run without this step.

So Yale needs to generate a real WAR and do a real deployment to a real application server, steps for which Maven is designed while Eclipse is specifically written to avoid or bypass. So instead of using this "interactive" compile and deploy technology, the safer alternative is to we use the "batch" approach of running a real "mvn install" to create the real WAR or EAR artifact, then a real install/deploy run a second Maven Installer project to copy the artifact to the regular deploy directory of the regular server. Then you You can still run Tomcat or JBoss under Eclipse for debugging in debug mode using an Eclipse plugin plugins like Mongrel (for Tomcat) or JBoss Tools. This allows you to set breakpoints and examine variable values in Eclipse. However, if you edit and save source in Eclipse then the change does not affect the running server. To make the change you have to stop the server, rerun the Maven Build and Installer jobs, and then restart the server.

The advantage of the "batch" approach is that you are guaranteed to get a 100% exact duplicate behavior as you will get later on when you run the Yale Jenkins jobs to compile and install the application onto the test or production servers. Eclipse does a pretty good job of doing almost exactly the same thing that Maven will do, but it is not worth several days of debugging to finally discover that almost the same thing is not quite as good as exactly the same thing. 

Eclipse recompiles each Java source file when you save it. Since the Eclipse project was created from the Maven POM, it compiles is configured to compile all the same source directories that Maven uses and it puts the would compile and to put the resulting class files in the same place Maven puts files when it compiles them. By default, Maven only recompiles a program if the source is newer than the class file. So normally, the Eclipse compiler always "wins" the race and all the source files in the project will have been compiled by Eclipse. If there is strange behavior and you believe it is due to differences in the Eclipse and Maven compile options, you can recompile everything by adding "clean" to the Maven goalsoutput directory. Because Eclipse compiles the source when the project is first built, and then recompiles source after every edit, whenever you run the "mvn install" job Maven finds that the class files are up to date and does not recompile the source. If it is important to have Maven recompile source itself, then you have to do a "mvn clean install" step. Also, neither Maven nor Eclipse does a good job cleaning up class files after a source file is deleted, so when you make such a change you should "clean" the project to force a recompile of the remaining files.

Running Maven Jobs Under Eclipse

...