JSF Workspace ist ein Tool zum Entwickeln von JSF Modulen mit Maven. Das Produkt kann aus dem Intersult Maven Repository bezogen werden.

Hintergrund#

Mit Maven können JSF-Web-Anwendungen, gebaut und mit dem tomcat6- oder tomcat7-maven-plugin gestartet werden. Dies ist sehr praktisch:
  • Das WAR wird durch Maven gebaut
  • Abhängige Projekte werden direkt referenziert
  • Kein zusätzlicher Build-Schritt notwendig, um JARs ins WAR zu kopieren
  • Das Projekte kann Konfigurationsfrei in einer lokalen Embedded-Tomcat-Instanz gestartet werden (im target-Folder)
  • Mit dem WAR Maven Plugin kann das Projekt in ${project.build.directory}/${project.build.finalName} (also target/name) gebaut und gestartet werden
  • Eclipse unterstützt durch das Maven-Eclipse-Plugin (M2E-Plugin) das synchrone Debuggen

Das M2E-Plugin stellt die Option Resolve Workspace Artifacts zur Verfügung. Das gestartete WAR-Projekt referenziert somit alle Maven-Artifakte die sich im Eclipse-Workspace befinden direkt und nicht mehr über das lokale Maven-Repository. Der Vorteil besteht in schneller Entwicklung der JARs, da kein kompletter Build-Zyklus mit Server-Neustart mehr notwendig ist.

In dieser Konfiguration arbeitet leider das Annotation-Scanning von JSF nicht mehr korrekt. Dadurch geht die Funktionalität der JSF-Annotationen in den referenzierten Workspace-JSF-JARs verloren.

Lösung#

JSF Workspace enthält einen Annotation-Scanner für genau diesen Zweck. Die Annotationen arbeiten damit wieder korrekt und es kann komplett im Workspace entwickelt werden:
  • Class-Dateien werden ohne Maven-Build direkt referenziert, falls Hotswap nicht ausreicht ist (wie üblich) ein Server-Neustart erforderlich.
  • Javascript, CSS-, XHTML-Dateien und andere Ressourcen werden upgedated

Dies bietet eine drastische Erleichterung beim Entwickeln von Taglibs und ähnlichen.

Configuration#

Die pom.xml kann zum Beispiel so konfiguriert werden:
		<finalName>${project.artifactId}</finalName>
		<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
		<extensions>
			<extension>
				<groupId>com.intersult</groupId>
				<artifactId>war-maven-plugin</artifactId>
				<version>1.0-SNAPSHOT</version>
			</extension>
		</extensions>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.5.1</version>
				<executions>
					<execution>
						<id>compile</id>
						<goals>
							<goal>compile</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat6-maven-plugin</artifactId>
				<version>2.0</version>
				<configuration>
					<port>80</port>
					<warSourceDirectory>${project.build.directory}/${project.build.finalName}</warSourceDirectory>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.0</version>
				<configuration>
					<port>80</port>
					<warSourceDirectory>${project.build.directory}/${project.build.finalName}</warSourceDirectory>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<version>2.5</version>
				<executions>
					<execution>
						<id>copy-jsp</id>
						<phase>compile</phase>
						<goals>
							<goal>copy-resources</goal>
						</goals>
						<configuration>
							<resources>
								<resource>
									<directory>src/main/webapp</directory>
								</resource>
							</resources>
							<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>
			
    <dependencies>
        ...
	<dependency>
		<groupId>com.intersult</groupId>
		<artifactId>jsf-workspace</artifactId>
		<version>1.0-SNAPSHOT</version>
		<scope>provided</scope>
	</dependency>
    </dependencies>
    
	<repositories>
		<repository>
			<id>intersult-repo</id>
			<name>Intersult Repository</name>
			<url>http://intersult.com/public/maven</url>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>intersult-repo</id>
			<name>Intersult Repository</name>
			<url>http://intersult.com/public/maven</url>
		</pluginRepository>
	</pluginRepositories>

Dabei reicht aus, die Dependency für JSF Workspace im Maven-Scope Provided rein zu nehmen, diese befindet sich beim Debugger-Start dann im Class-Path. Im finalen WAR wird sie nicht mit eingebunden, da ist sie schließlich nicht erforderlich.

Hier die M2E Launch-Config für den embedded Tomcat 7 über das tomcat7-maven-plugin