Versions Compared

Key

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

CAS was created at Yale and Versions 1 and 2 of the CAS code were written at Yale. Version 3 was completely rewritten and has been managed by a group of universities called "JA-SIG". Recently JA-SIG merged with Sakai to and was renamed "Apereo".  In Yale CAS documentation, any reference to jasig.org should be understood to now reference apereo.org.

The CAS

...

Project Directory Structure

Any given release of the CAS Server can be downloaded as a zip file from Apereo or it can be checked out from the Git server used by CAS developers as documented at the Apereo Web site. Yale modifies this file, adds additional subdirectories representing the Yale customizations, and then checks it into Yale's Subversion server where the Yale standard Build process begins. Depending on context the CAS "project" could mean the original zip file or the modified file stored in SVN.

The CAS Project is structured as a "parent Maven project with subprojects". This is a common Maven way to package multiple projects that have to be compiled and built in a particular order. The outer directory contains the parent or master POM that establishes parameters shared by all the subprojects and a list of the subprojects to be built in the order in which they should run.

Each subproject creates a JAR or WAR file. The first project is cas-server-core and it contains about 95% or more of all the CAS code. It has to be built first because all the other projects depend on it. After that, there are projects to create optional components that you may or may not choose to use.

Building the WAR

The CAS WAR that you actually run in the Web server is built in two steps in two Maven projects.

Apereo distributes a project called cas-server-webapp to create an initial prototype WAR file. The WAR it creates is not particularly useful, but it contains at least a starter version of all the Spring XML used to configure CAS and many CSS, JSP, and HTML pages. It also contains a WEB-INF/lib with the basic JAR libraries needed by a basic CAS system.

Although you can modify the cas-server-webapp project directly, Apereo recommends using the WAR Overlay feature of Maven. This simplifies the case where the only changes you are making to CAS is to replace specific JSP and HTML pages with your own wording, or CSS files with your own look and feel, or Spring XML beans configured differently. In a WAR Overlay project you reference a "template" WAR containing a starting set of files (the WAR created by cas-server-webapp in this case) and then you include in your WAR Overlay project only the things you want to change or add. Maven copies the template WAR file to the output artifact, but it replaces any file in the template that has the same name as a file in the Overlay project, and it adds any file in the Overlay project that doesn't exist in the template. Therefore the Overlay project only contains Yale changes and doesn't have to include all the unchanged Apereo vanilla files.

If you use any of the optional modules (ehcache, ldap, oauth, etc.) then you configure them in the Overlay project in modified Spring XML files and include them as dependencies in the Overlay project POM. Since you cannot include a JAR library until after it has been created, the Overlay project should be the last project executed, except possibly for projects that generate Javadoc or other documentation.

The Yale Overlay project is in a directory called cas-server-yale-webapp. However, Eclipse frequently pulls out an internal original name for the project and so it often displays as cas-server-war.

At Yale, when you run the Jenkins Build job for CAS, the result of that job is to create a cas.war file and store it in the Yale Artifactory server with a version number and some hierarchical naming. An example is Version 1.1.1 of the Yale CAS Server stored as https://repository.its.yale.edu/maven2/libs-releases-local/edu/yale/its/cas/cas-server-war/1.1.1/cas-server-war-1.1.1.war. However, you cannot build the WAR until you build everything it depends on. The Jenkins Build job runs the parent Maven project in the top level directory, and it creates the WAR file by first building everything it depends on.

The Parent Project

Whenever Yale decides to upgrade from one release of CAS to another, a major part of the work is to adapt the old Yale parent project (the pom.xml file in the root of the CAS Project directory) to the new release. This is not a case where you are simply modifying some Apereo file with Yale changes. The parent project reflects the thing you are building.

Apereo is building a template version of CAS that doesn't do anything particularly interesting but at least creates vanilla versions of all the JAR and WAR files. The most important thing is that these files conform to the rules for Open Source projects distributed publicly. They have to have the right copyright statements and the right license boilerplate.

Yale is building a version of CAS that has to satisfy Yale internal needs. It doesn't care about copyright statements or licenses because we are not giving this code to anyone else. We can strip out all the list of developers and contributors not because we don't appreciate their contributions but because it is not particularly relevant to doing the Yale customizations.

These are really two quite different objectives and they have a fairly large impact on the structure of the parent POM. As a result, you have to merge elements from the old Yale parent and the new Apereo parent. This requires a tour of the Yale version of the parent POM.

  • Version - The Apereo parent will have the version number of the CAS release (say 3.5.2.1). The Yale parent will have the version that Yale internally assigns to its CAS artifact (1.1.1-SNAPSHOT for example). The general rule is that Apereo projects and artifacts retain their old version number unless they are changed, but if Yale has to make a single line of modification to a project then it has become a Yale project and be renumber to the Yale development cycle. Fortunately, CAS started at JASIG with 3.x so we can number anything 1.x without conflict.
  • SCM - defines the Yale Subversion server where Yale maintains its production source and not the Apereo Git server used to develop new releases.
  • Repositories - defines Yale's Artifactory, but merged with other sources for artifacts from the Apereo pom.
  • pluginManagement - Maven is a modular system with extensible functions provided by plugin modules. When a project requires special configuration or processing, it can add parameters to the configuration of a particular plugin in this section of the POM file. For the most part Yale copies this section from the Apereo POM file, but specific parameters have to be changed as a secondary result of Yale decisions. For example, because we choose to run CAS under Java 1.7 instead of 1.6, the version of the aspectj-maven-plugin has to be increased from "1.4" as distributed by Apereo to "1.5". When you run the Yale Jenkins Build job operation "Perform Release", which takes version "1.1.1-SNAPSHOT" source, creates a "1.1.1" version tag and artifact, and then leaves SVN set to develop "1.1.2-SNAPSHOT", then running unit tests in the middle of the operation is not helpful and is disabled at Yale by adding <arguments>-Dmaven.test.skip=true</arguments> to the configuraton of the maven-release-plugin.
  • dependencyMangement - All the Apereo code is coordinated to use the same release of every dependency JAR file. However, Apereo does not bother to specify explict Versions of secondary dependencies (that is, JAR files required by a library that CAS uses). However, when Yale adds its own code to the mix, we may depend on a particular version of a library where the default behavior of Maven previously selected a different verision of the same library. For example, in CAS 3.5.2.1, cas-server-core depends on a library that itself depends on commons.io and from the chain of pom files Maven selects commons.io Version 2.0. Yale code requires Version 2.4. When two different subprojects independently resolve to different versions of the same dependency, the parent POM has to decide which wins. Basically this second should contain the latest version selected by either Apereo or Yale (and of course nobody should use a library whose developers are dumb enough not to maintain reasonable backward compatibility).
  • modules - Yale wants to use vanilla code distributed by Apereo. If we have no changes to distributed CAS code, then there is no reason to recompile it. So initially Yale comments out all the modules that Apereo wrote and adds in uncommented module statements for the Yale developed projects. Therefore, the Build process only compiles and builds the Yale changes. However, if it is necessary to make a change to Apereo code then a changed module has to be uncommented so it can be rebuilt. Also, when you check out code into a new Eclipse directory you may uncomment the module statement for an important project and then tell Eclipse to generate an Eclipse project to build that module, but after you have your Eclipse project you revert back to the version of the POM where the module is commented out. Letting Eclipse configure the project and compile the code once gives you all the Eclipse IDE stuff for classes and methods built by that module and it lets you trace into the module source during debugging.

 

Yale adds several new Yale specific subprojects to the vanilla Apereo Maven source project directory tree. Some of the projects create JAR files that add specific functions to CAS. The final project builds the actual WAR file that is deployed to JBoss to run the CAS Server at Yale. No changes are made to the Apereo code unless there is a bug that needs to be fixed immediately.

...