Versions Compared

Key

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

...

The ReleaseNotes.html file in in the root of the cas-server project will identify the current state of new directories and any modified files. This should be a descriptive match for the physical code change history in SVN.

Yale and JASIG use Eclipse as the IDE. The most current version of Eclipse works best. Start with the J2EE package of Eclipse. Use the Help - Eclipse Marketplace tool to add support for Subversion (use Subversive), Maven (M2E), AspectJ (AJDT), and the add the M2E-AspectJ support from Add Software source http://dist.springsource.org/release/AJDT/configurator/. You are certainly free to add other Eclipse features for other development.

Note: As of March 2014 the M2E-AspectJ support does not work correctly. When installed, it generates a null pointer exception creating a Maven Run Configuration job. Until this is fixed, do not install it. This will mean, however, that when M2E imports the POM files it will complain that the Maven AspectJ plugin function is not support by Eclipse M2E. Ignore these messages as they have no effect on this development process.

Check Out and Build the Project

Open the SVN Repository Exploring "perspective" (page) of Eclipse and define the repository url. Right click the trunk of the current CAS source project and select the simple Check out menu option. Do not run the Check Out As wizard or try at this point to make it a Java project. Simple check out creates an Eclipse "project" directory in the workspace but at this point it has no attributes or nature or build process.

Now return to the J2EE perspective, right click the new project directory, and choose Import - Maven - Existing Maven Projects. The Eclipse support for Maven will search the directory for its POM and then find POM files in the subdirectories.It will then display a list of the subdirectories that contain Maven projects listed in the parent POM. Select the checkbox for all of them and push the Next button. The next panel displays the status of Maven plugins and Eclipse support. Ignore the errors (to be Resolved Later) and press Finish. Ignore the popup box that warns you that the project will have build errors. This simply means that Eclipse itself cannot do the complete build and you will have to run Maven under Eclipse to create a fully functional CAS server.

At this point Eclipse will do a lot of work. It is running through all the POM files understanding what they say and is downloading from the internet into the local Maven repository all the JAR files that any of the CAS projects identify as a dependency. It creates an Eclipse project with Eclipse compile options and an Eclipse "Build Path" that as closely as possible matches everything in the POM file.

At the end there should be several types of error messages that don't really matter:

  • JSP, HTML, XML, XHTML, and JavaScript files may report errors because Eclipse is trying to validate syntax without having everything it needs to do the validation properly, or because some files are fragmentary and have to be assembled from pieces before they are well formed.
  • You can get Build Path error if you only have a JDK 1.7 or later installed on your machine, because the Maven template used to translate POM files automatically defaults to 1.6 or earlier. CAS should run fine on later versions of Java, or you can manually change each generated project to use 1.7 as the compiler level.

Generally, there should only be Warning level Java messages. Note: If the M2E AspectJ support is not installed, there will be warning and error messages that the M2E component in Eclipse does not support the AspectJ Maven plugin functions referenced in the POM. Ignore these messages and any warning that the project will have resulting "build errors". This will not really be a problem.

Before the import, there was only the "cas-server" project (and the installer). The import creates an Eclipse "shadow project" (my name) for every subdirectory under cas-server that is needed. These shadow projects are Eclipse entities built from the Maven POM files. They contain Eclipse configuration and option elements (what Eclipse thinks of as the project and Build Path). What these shadow projects don't have are real source files. They contain configuration pointers the real source files in the subdirectories of the cas-server project. As you open and look at these projects, they will appear to have source. However, this source will be structured as Java Packages and Java Classes and Java Resources. This is a logical representation in Java and WAR terms of the actual source files that remain as subdirectories of the cas-source directory.

In a few cases, such as the Search option on the menu, you may look for files with certain text or attributes and the results of the search will display the same file twice, once as a physical text file in the cas-server directory tree and once as a Java Class source in the corresponding Eclipse project. Just realize that these are two different views of the same file, and changes you make to either view are also changes to the other view.

Interactive and Batch Modes

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

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, 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. Artifacts are what Maven builds. Eclipse compiles source and holds resource files in its workspace and it tries to do something 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, 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, we use the "batch" approach of running a real "mvn install" to create the real WAR, then run a second Maven Installer project to copy the artifact to the regular deploy directory of the regular server. You can still run Tomcat or JBoss under Eclipse in debug mode using Eclipse 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 serverCAS runs in production on Red Hat Enterprise Linux, but you can do development with Eclipse and JBoss running on Windows or any other OS. If you plan to work on SPNEGO, however, you should use a Linux development machine or VM because SPNEGO behavior depends on the native GSSAPI stack in the OS and that is different in Windows from the version of the stack in Linux.

Yale uses Eclipse as the Java IDE. If you do not already have Eclipse installed, start with the J2EE download package of the current release from eclipse.org. Eclipse adds previously optional features to later releases. Anything that does not come preinstalled can be added using the Help - Install New Software ... menu (if the option is an Eclipse project) or the Help - Eclipse Marketplace menu (Eclipse and third party tools, but check carefully because the Marketplace lists versions for every different release of Eclipse). You need:

  • Maven support (M2E) which appears to be standard in the latest releases.
  • Subversion support (Subversive) which is not automatically included because there were several competing projects. The first time you run a Subversive window you will get a popup to install a third party (Polarion) connector from a list and you should choose the latest version of SVNKit).
  • JBoss Tools (at least the JBossAS manager) which is listed in Marketplace because it comes from Red Hat.
  • AJDT, the Eclipse support for AspectJ which the JASIG CAS source uses.
  • Ideally you would add the M2E-AspectJ support by adding the update URL http://dist.springsource.org/release/AJDT/configurator/ to the Install New Software menu, but as of March, 2014 this Eclipse plugin does not work (it generates a null pointer exception editing the Maven Run Configurations. Until this is fixed, do not install it. This will mean, however, that when M2E imports the POM files it will complain that the Maven AspectJ plugin function is not support by Eclipse M2E. Ignore these messages as they have no effect on this development process.
  • The standard Maven support comes with a version of Maven 3 built into Eclipse. That is exactly right for building the CAS executable, but it is a Yale convention that the Install job that copies the WAR file over to JBoss has to run under Maven 2. So you need to download the last Maven 2.2.1 from apache.org and unzip it to a directory somewhere on your disk. Later on you will define this directory to Eclipse as a optional "Maven Installation" it can use to run jobs configured to use Maven 2 instead of the default 3.

Check Out and Build the Project

Open the SVN Repository Exploring "perspective" (page) of Eclipse and define the repository url https://svn.its.yale.edu/repos/cas. This directory contains various cas clients and servers. Find the trunk of the current cas-server project and check it out.

The cas-server project is a Maven "parent" project with subprojects in subdirectories. Although CAS is written in Java, it is the subprojects/subdirectories of cas-server that are Java projects. The parent directory just has a Maven pom. So do not use the Check Out As wizard or assume that you need to tell Eclipse what type of project it is. Just do a simple Check Out of a bunch of files into a project directory, and after that we tell Eclipse that it is a Maven project.

Return to the J2EE perspective, right click the new cas-server project directory, and choose Import - Maven - Existing Maven Projects. The Eclipse support for Maven will search the directory for its POM and then find POM files in the subdirectories.It will then display a list of the subdirectories that contain Maven projects listed in the parent POM. All the projects should be checked, then click the Next button. The next panel displays the status of Maven plugins and Eclipse support.

At this point, if the M2E-AspectJ support has not been installed in Eclipse you will get error messages that Eclipse does not know how to emulate the Maven AspectJ plugin support. There are Eclipse plugins and Maven plugins. M2E is a package of Eclipse plugins that attempts, more or less, to duplicate all the important functions of the most frequently used Maven plugins. However, it does not require much effort to use a Maven option that Eclipse does not know how to emulate. This does not matter to CAS development because we are going to use real Maven processing to build the CAS executable. However, it is useful for Eclipse to do as much Maven processing as it can so that the source files display without error markers and you can use all the Eclipse tools. Lack of AspectJ support in Eclipse does not affect CAS development, but you will get some error messages warning you that Eclipse has notice a Maven feature it cannot emulate and you have to ignore them. Click OK to ignore the AspectJ "build error" messages.

A Maven project has standard source directories (src/main/java) used to build the output JAR or WAR artifact. A Maven POM has "dependency" declarations it uses to download JAR files (to your local Maven repository) and build a "classpath" used to find referenced classes at compile time. Eclipse has a "Build Path"  (physically the .classpath file) that defines source directories, the location where the ouput class files are stored, and the libraries that have to be used to compile the source. M2E runs through the POM files in each subproject and creates a Eclipse project with a Eclipse Build Path that tells Eclipse to do exactly the same thing Maven would do to the same project. Eclipse will compile the same source in the same source directory and produce the same output to the same output directory using the same JAR libraries to run the compiler. It is important (because it answers questions later on) that you understand that Eclipse is being configured to do MOSTLY the same thing that Maven would do, but Eclipse does it without running Maven itself. The MOSTLY qualification is that M2E sets default values for the enormous number of options that an Eclipse project has (what error message to display or hide, syntax coloring, everything else you can set if you right click the project and choose Preferences from the menu). After M2E creates an initial default batch of project setting, you are free to change them and ask Eclipse to do things slightly different without breaking the development process.

At the end there should be several types of error messages that don't really matter:

  • JSP, HTML, XML, XHTML, and JavaScript files may report errors because Eclipse is trying to validate syntax without having everything it needs to do the validation properly, or because some files are fragmentary and have to be assembled from pieces before they are well formed.
  • The M2E default is to configure the Eclipse project to use Java 1.6 both as a language level for the compiler and as a JRE library default. If you are running on a machine with 1.7 or 1.8, you will get warning messages that the project is set up for 1.6 but there is no actual 1.6 known to Eclipse. You can ignore this message, or correct the default project settings.

Before the import, there was only the "cas-server" project (and the installer). The import creates an Eclipse "shadow project" (my name) for every subdirectory under cas-server that is needed. These shadow projects are Eclipse entities built from the Maven POM files. They contain Eclipse configuration and option elements (what Eclipse thinks of as the project and Build Path). What these shadow projects don't have are real source files. They contain configuration pointers the real source files in the subdirectories of the cas-server project. As you open and look at these projects, they will appear to have source. However, this source will be structured as Java Packages and Java Classes and Java Resources. This is a logical representation in Java and WAR terms of the actual source files that remain as subdirectories of the cas-source directory.

In a few cases, such as the Search option on the menu, you may look for files with certain text or attributes and the results of the search will display the same file twice, once as a physical text file in the cas-server directory tree and once as a Java Class source in the corresponding Eclipse project. Just realize that these are two different views of the same file, and changes you make to either view are also changes to the other view.

Interactive and Batch Modes

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

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, 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 the running and debugging of applications under JBoss or Tomcat that Eclipse may attempt to be too simple.

J2EE servers have a "deployment" directory where you put the WAR file that contains the Java classes and HTML/XML/JSP/CSS files. You can deploy the application as a single ZIP file, or you can deploy it as a directory of files.

Most Java application servers have a Hot Deploy capability that allows you to replace a single HTML or CSS file in the (non-ZIP, directory of files) application and the server will notice the new file with its new change date and immediately start to use it. This can ever work for some individual class files. However, Hot Deploy behavior is random and error prone if you attempt to change a number of files at the same time because the application server can notice some changes in the middle of the update and start to act on an incomplete set of updates.

Eclipse likes the idea of a simple change to a single HTML, CSS, or even a simple Java source file taking effect immediately after you save the file in the editor. However, since it knows that Hot Deploy doesn't actually work if you physically copy a batch of files over to the Tomcat or JBoss deploy directory, the Eclipse J2EE runtime support has traditionally attempted to do something much more sophisticated. It "hacks" the normal Tomcat configuration file to insert a special Eclipse module that creates (to Tomcat) a "virtual" WAR file that does not actually exist in the Tomcat deploy directory but which is synthetically emulated by Eclipse using the source and class files that it has in the projects in its workspace.

This is a little better than Hot Deploy, because Eclipse can simulate swapping the entire set of changed files in a single transaction, but in the long run it doesn't work either. CAS, for example, is a big Spring application with a bunch of preloaded Spring Beans created in memory when the application starts up. The only way to change any of these beans is to bring the entire application down and restart it.

So successful CAS development requires you, even if all you want to do is change the wording on an HTML file, to stop the application server, run a real "mvn install" on the cas-server project to build a new WAR file, run a "mvn install" on the Installer project to copy it over to the application server deploy directory, and then restart the application server. The Eclipse capability to make some changes take effect immediately on a running server is simply too unreliable, and because of that we cannot use the entire "interactive" Eclipse application build strategy but must instead switch to a Maven "batch" artifact building and deployment process.

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.

...