Archive

Archive for the ‘Maven’ Category

Quality Center Mylyn Integration

Wednesday, 28. October 2009 Andreas Höhmann Leave a comment

There is a interesting project at sourceforge called qcMylyn.  The projects aims to provide a Mylyn connector for Quality Center. Support Eclipse 3.4.2, 3.5, Mylyn 3.0.5+.

I tried the released version 0.2.4 but it didn’t work because at work we are using an older version of QualityCenter (9.1). But this was no big problem I have the sourcecode (OS rocks) and I’m a programmer ;)

I found out that a other project called QcTools4J contains the java code for manipulation a QC system. They using a com4j bridge to bind QC’s otaclient.dll.

If you have trouble with a older/newer version of QC you have to update the qctools4j.

You find a short tutorial how to update qctools4j here. (read this first) … then you will come to the point where you want create a new otaclient.jar from you local otaclient.dll. Here is my simple solution for that.

I create my own otaclient maven project with the following pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>otaclient</groupId>
      <artifactId>otaclient</artifactId>
      <version>9.1.0.4372</version>
      <dependencies>
        <dependency>
          <groupId>org.jvnet.com4j</groupId>
          <artifactId>com4j</artifactId>
          <version>20080107</version>
        </dependency>
      </dependencies>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.5</source>
              <target>1.5</target>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.jvnet.com4j</groupId>
            <artifactId>maven-com4j-plugin</artifactId>
            <executions>
              <execution>
                <id>gen-java-bridge</id>
                <goals>
                  <goal>gen</goal>
                </goals>
                <configuration>
                  <file>src/qc/OTAClient.dll</file>
                  <package>com.mercury.qualitycenter.otaclient</package>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </project>

I using the maven-com4j-plugin to generate the java layer for otaclient.

All you have to do is to extract your “qc client package” (could be download from every qc server page) into src/qc and start mvn clean package.

Then target will contain a otaclient-9.1.0.4372.jar. Copy this jar into qctools4j/lib/com.mercury.qualitycenter.otaclient-9.2.jar and rebuild qctools4j. That’s all :)

qcmylyn_otaclient

Then copy the qctools4j.jar into org.tszadel.qctools and rebuild the whole eclipse feature.

qcmylyn_qctools4j

Try it :)

How to use multiple maven versions parallel

Thursday, 3. September 2009 Andreas Höhmann Leave a comment

I need (two) different maven versions in my development system, a actual maven (2.2.1) for the “normal” work and a tycho-maven for eclipse-osgi projects (i.e. m2eclipse).

Setup maven installations

  • I created two directories maven-repos and maven-distro
  • Download maven (2.2.1) from http://maven.apache.org/download.html, unpack into maven-distro
  • Download maven-tycho (0.4.0-DEV*) from https://docs.sonatype.org/display/M2ECLIPSE/Tycho+builds, unpack into maven-distro
  • Go into maven-distro/maven-tycho/bin and rename all mvn*** into tycho***
  • Create a repository path for each maven

The result should look like this:

multiple_maven_installation

multiple_maven_installation_tycho

Configure maven installations

The tycho maven in D:\maven-distro\maven-tycho\conf contains a settings-tycho.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository>D:\maven-repos\maven-tycho</localRepository>
</settings>

and a settings.xml (this is the changed “standard” maven configuration):

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/settings/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <profiles>
    <profile>
      <id>tycho-default</id>
      <repositories>
        <repository>
          <id>forge</id>
          <url> http://repository.sonatype.org/content/groups/public</url>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
          <releases>
            <enabled>true</enabled>
          </releases>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>forge</id>
          <url> http://repository.sonatype.org/content/groups/public</url>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
          <releases>
            <enabled>true</enabled>
          </releases>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>tycho-default</activeProfile>
  </activeProfiles>
</settings>

The standard maven in D:\maven-distro\maven-2.2.1\conf must not be changed. So this maven will use the default settings.xml and a user-settings from $HOME/.m2/settings.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository>D:\maven-repos\maven</localRepository>
</settings>

Configure development environment

I use cygwin under windows, so i can put the maven-tycho-alias into my ~/.bashrc:

# Add maven-tycho to path
alias mvnTycho="tycho -s \"d:/maven-distro/maven-tycho/conf/settings-tycho.xml\""
export PATH="/cygdrive/d/maven-distro/maven-tycho/bin":$PATH

Usage

hoehmann@foobar /bin
$ mvnTycho --version
Apache Maven 3.0-TYCHO-797695 (r797704; 2009-07-25 04:43:26+0200)
Java version: 1.5.0_12
Java home: d:\java\jdk1.5.0_12\jre
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

hoehmann@foobar /bin
$ mvn --version
Apache Maven 2.2.0 (r788681; 2009-06-26 15:04:01+0200)
Java version: 1.5.0_12
Java home: d:\java\jdk1.5.0_12\jre
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

With this i can run mvn for “normal” maven projects, this will start maven 2.2.1 from maven-distro/maven/ and the repo will be at maven-repo/maven/.

Or i can run mvnTycho for “osgi” maven projects, this will start tycho from maven-distro/maven-tycho/ and the repo will be at maven-repo/maven-tycho/.

You can do this with much more versions (2.0.1, 2.1.0, 2.2.0) and each maven will have a own repository.

Try it :)

Categories: Maven Tags: , ,

Use Maven Artifact Version in Eclipse Code Templates

Monday, 24. August 2009 Andreas Höhmann 1 comment

Based on waffel’s blog i wrote a eclipse plugin which provides the current artifact-version of a maven-project to the eclipse editor-templates. Waffel want to add the current plugin id/version to the @since field for class comments, i want to add the current version of my maven-eclipse-project. Let me explain my solution.

It’s easy to add a new template-variable to eclipse, you can read this. Based on  org.eclipse.jface.text.templates.TemplateVariableResolver we can write a MavenVersionResolver:


/**
 * Resolver to resolve variable <code>pomVersion</code>.
 *
 * @author hoehmann
 * @since 1.0.0
 */
public class MavenVersionResolver extends TemplateVariableResolver {

  public MavenVersionResolver() {
    super();
  }

  private String getMavenVersion(final IProject project) {
    if (project == null) {
      throw new IllegalArgumentException("Missing project"); //$NON-NLS-1$
    }
    String result = ""; //$NON-NLS-1$
    try {
      if (project.hasNature(IMavenConstants.NATURE_ID)) {
        final MavenProjectManager projectManager = MavenPlugin.getDefault()
            .getMavenProjectManager();
        final IMavenProjectFacade projectFacade = projectManager.create(
            project, new NullProgressMonitor());
        if (projectFacade != null) {
          final ArtifactKey mavenProject = projectFacade.getArtifactKey();
          if (mavenProject != null) {
            result = mavenProject.getVersion();
            // remove snapshot-indicator
            final int index = result.lastIndexOf("-SNAPSHOT"); //$NON-NLS-1$
            if (index != -1) {
              result = result.substring(0, index);
            }
          }
        }
      }
    } catch (final CoreException ex) {
      MavenLogger.log(ex);
    }
    return result;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected String resolve(final TemplateContext context) {
    // TODO better way to get the project?!
    return getMavenVersion(((CodeTemplateContext) context).getJavaProject()
        .getProject());
  }
}

With the MavenProjectManager from m2eclipse we can create a IMavenProjectFacade, this facade returns the ArtifactKey and this key have the version. If the version is a snapshot-version we can cut this trailing string off and the result is the (next) version for our maven-project (for me it doesn’t make sense to add the snapshot-version into a @since comment because the release-version should be documented in the sourcecode).

Maybe the check for the “m2eclipse”-nature is not necessary:

if (project.hasNature(IMavenConstants.NATURE_ID)) {....}

I tried without the nature-check and it works. The project must contain a “pom.xml” to get a IMavenProjectFacade.

This was the first part of the solution. The placeholder “pom_version” will be available for all editor-templates in the “java-context”:

maven_version_editortemplate

Waffel described already a solution (a workaround) to use a editor-template-resolver in the code-templates. He registered a IStartup class which copies his own BundleIdResolver/BundleVersionResolver into the (internal) code-template-context-registry of the Eclipse-Java-Plugin. For waffel this was fine because he doesn’t register his resolvers as editor-template-resolvers. I want use my MavenVersionResolver in all java-templates and in the code-templates.

And i don’t want create a new instance of the resolver, i want reuse the extension-point-configured resolver. So i have only one place to define my resolver (type = ‘pom_version’, localized name, localized description, class etc.).

I found a other way to register the resolver

  1. i search my MavenVersionResolver in the registered editor-templates (java-context)
  2. if i found one, i add this reference to the (internal) code-template-registry


/**
 * Currently it's not possible to provide more variables for
 * <tt>java-code-templates</tt>, we can only add more <tt>editor-templates</tt>
 * via extension-point.
 *
 * <p>
 * This {@link IStartup} is a workaround to register our
 * {@link MavenVersionResolver} for <tt>java-code-templates</tt> too.
 * </p>
 *
 * @author hoehmann
 * @since 1.0.0
 */
public class RegisterResolvers implements IStartup {

  private static final String JAVA_PLUGIN_ID = "org.eclipse.jdt.ui"; //$NON-NLS-1$

  /**
   * Add our resolver to each registered code-template-context.
   *
   * @param javaPlugin
   *          must not be <code>null</code>
   * @param mavenVersionResolver
   *          must not be <code>null</code>
   */
  private void addMavenVersionResolver(final JavaPlugin javaPlugin,
      final MavenVersionResolver mavenVersionResolver) {
    Assert.isNotNull(javaPlugin);
    final ContextTypeRegistry codeTemplateContextRegistry = javaPlugin
        .getCodeTemplateContextRegistry();
    Assert.isNotNull(codeTemplateContextRegistry);
    final Iterator ctIter = codeTemplateContextRegistry.contextTypes();
    while (ctIter.hasNext()) {
      final TemplateContextType contextType = (TemplateContextType) ctIter
          .next();
      contextType.addResolver(mavenVersionResolver);
    }
  }

  /**
   * {@inheritDoc}
   */
  public void earlyStartup() {
    // check if plug-in org.eclipse.jdt.ui is final already active
    final Bundle bundle = Platform.getBundle(JAVA_PLUGIN_ID);
    if (bundle != null && bundle.getState() == Bundle.ACTIVE) {
      registerResolvers();
    } else {
      // register listener to final get informed, when plug-in final becomes
      // active
      final BundleContext bundleContext = Activator.getDefault().getBundle()
          .getBundleContext();
      bundleContext.addBundleListener(new BundleListener() {
        public void bundleChanged(final BundleEvent pEvent) {
          final Bundle eventBundle = pEvent.getBundle();
          if (!eventBundle.getSymbolicName().equals(JAVA_PLUGIN_ID)) {
            // ignore other plugins
            return;
          }
          if (eventBundle.getState() == Bundle.ACTIVE) {
            registerResolvers();
            bundleContext.removeBundleListener(this);
          }
        }
      });
    }
  }

  /**
   * Try to find our {@link MavenVersionResolver} in the java-plugin
   * template-context-registry.
   *
   * @param javaPlugin
   *          must not be <code>null</code>
   * @return
   */
  private MavenVersionResolver getMavenVersionResolver(
      final JavaPlugin javaPlugin) {
    Assert.isNotNull(javaPlugin);
    final ContextTypeRegistry contextRegistry = javaPlugin
        .getTemplateContextRegistry();
    Assert.isNotNull(contextRegistry);
    final TemplateContextType javaContextType = contextRegistry
        .getContextType(JavaContextType.ID_ALL);
    Assert.isNotNull(javaContextType);
    final Iterator<TemplateVariableResolver> resolvers = javaContextType
        .resolvers();
    MavenVersionResolver mavenVersionResolver = null;
    while (resolvers.hasNext()) {
      final TemplateVariableResolver resolver = resolvers.next();
      if (resolver instanceof MavenVersionResolver) {
        mavenVersionResolver = (MavenVersionResolver) resolver;
        break;
      }
    }
    return mavenVersionResolver;
  }

  /**
   * First find the maven-version-resolver from the registered resolvers.
   */
  private void registerResolvers() {
    final JavaPlugin javaPlugin = JavaPlugin.getDefault();
    if (javaPlugin == null) {
      throw new IllegalStateException(String.format(
          "Expected plugin '%s' is not available", JAVA_PLUGIN_ID));
    }
    final MavenVersionResolver mavenVersionResolver = getMavenVersionResolver(javaPlugin);
    if (mavenVersionResolver != null) {
      addMavenVersionResolver(javaPlugin, mavenVersionResolver);
    }
  }
}

Now its possible to use “pom_version” in code-templates too:

maven_version_codetemplate

Now the final test  …  create a “normal” java-project, create a new class. The javadoc will not contain a version (the project doesn’t have a maven-nature):

maven_version_test_without_m2eclipse

If the project is a “real” maven project the version will be available:

maven_version_test_with_m2eclipse

If anyone need the plugin … leave a comment.

Deploy maven war-project to tomcat

Friday, 10. July 2009 Andreas Höhmann Leave a comment

With maven it’s possible to deploy the current version of your webapplication (<packaging>war</packaging>) with one command!

mvn clean package tomcat:deploy-only

All we have to to is to define the tomcat-maven-plugin:


...
<packaging>war</packaging>
...
<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>tomcat-maven-plugin</artifactId>
 <configuration>
 <url>http://server[:port]/manager</url>
<path>/${project.build.finalName}</path>
 <update>true</update>
<server>tomcat_xyz</server>
 </configuration>
 </plugin>

You have to define username/password in your settings.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
 http://maven.apache.org/xsd/settings-1.0.0.xsd">

<servers>
<server>
<id>tomcat_xyz</id>
<username>admin</username>
<password>123geheim</password>
</server>
</servers>

</settings>

Check the tomcat-user.xml:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
 <role rolename="manager"/>
 <role rolename="admin"/>
 <user username="admin" password="123geheim" roles="admin,manager"/>
</tomcat-users>

If you  run the maven command you will see:

[INFO] [tomcat:deploy-only {execution: default-cli}]
[INFO] Deploying war to http://server:8080/foobar-1.0.0-SNAPSHOT-B20090710  
[INFO] OK - Deployed application at context path /foobar-1.0.0-SNAPSHOT-B20090710
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

To get the version and a buildnumber in the context-path you must define the finalName and you must use a “buildnumber-plugin”, e.g.  buildnumber-maven-plugin or maven-timestamp-plugin:


<build>
 <finalName>foobar-${project.version}-B${buildNumber}</finalName>
 </build>
<plugins>
<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>buildnumber-maven-plugin</artifactId>
 <executions>
 <execution>
 <id>create-buildnumber</id>
<phase>validate</phase>
 <goals>
 <goal>create</goal>
 </goals>
 </execution>
 </executions>
 <configuration>
 <doUpdate>false</doUpdate>
 <doCheck>false</doCheck>
 <format>{0,date,yyyyMMdd}</format>
 <items>
 <item>timestamp</item>
 </items>
 <buildNumberPropertyName>buildNumber</buildNumberPropertyName>
</configuration>
 </plugin>
<plugin>
 <groupId>com.keyboardsamurais.maven</groupId>
 <artifactId>maven-timestamp-plugin</artifactId>
 <executions>
 <execution>
 <id>create-buildnumber</id>
 <goals>
 <goal>create</goal>
 </goals>
 <configuration>
<propertyName>buildNumber</propertyName>
 <timestampPattern>yyyyMMdd</timestampPattern>
 </configuration>
 </execution>
 </executions>
 </plugin>

</plugins>

Nexus Pro verwaltet Eclipse-Repositories

Monday, 8. June 2009 Andreas Höhmann Leave a comment

Mit Hilfe von Nexus-Pro (Version 1.3.2) ist es möglich Eclipse-Plugin-Repositories zu verwalten.

Damit wird es möglich für ein Entwicklungsteam eine Liste von Plugin-Repositories zentral zu verwalten. Alle Entwickler stellen in ihrem Eclipse Update Manager nur noch dieses eine Repository (Nexus) ein und fertig :)

Vorteile:
- externer Netzwerktraffic wird reduziert
- Thema Sicherheit, Entwickler müssen nicht unbedingt ins Internet (Proxy etc.)
- man sieht zentral welche Plugins, in welchen Versionen verwendet werden

Kurzes Video hier: http://vimeo.com/4102464

Categories: Eclipse, Nexus Tags: , , ,

Hibernate sql logging with values

Wednesday, 3. June 2009 Andreas Höhmann Leave a comment

As you might know already, Hibernate supports logging for sql-statements. Your Spring-configuration (e.g. spring-database.xml) must contain this:


<bean id="entityManagerFactory"
 class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="logging-test" />
<property name="jpaVendorAdapter">
 <bean>
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="${jpa.hibernate.dialect}" />
 </bean>
 </property>
<property name="jpaProperties" value="hibernate.dialect=${jpa.hibernate.dialect}" />
 </bean>

With showSql=true hibernate will show you logmessages like this:

Hibernate:
   delete
   from
      SoftwareCategory_SoftwareCategory
   where
      SoftwareCategory_id=?
Hibernate:
   update
      SoftwareCategory
   set
      concurrentVersion=?,
      CATEGORY_NAME=?,
      PARENT_ID=?
   where
      id=?
      and concurrentVersion=?
Hibernate:
   insert
   into
      SoftwareCategory_SoftwareCategory
      (SoftwareCategory_id, POSITION, children_id)
   values
      (?, ?, ?)

To see the values and not the placeholders (?) you must define the loglevel trace for hibernate-types in the log4j.xml:


<category name="org.hibernate.type">
<priority value="trace" />
 </category>

Then you will see logmessages like this:

Hibernate:
   insert
   into
      SoftwareCategory_SoftwareCategory
      (SoftwareCategory_id, POSITION, children_id)
   values
      (?, ?, ?)
NullableType:151 - binding '68' to parameter: 1
NullableType:151 - binding '0' to parameter: 2
NullableType:151 - binding '69' to parameter: 3

Not bad but there is a better way for this :-)

Yesterday i found the project JDBCLogger.  They have implemented a “JDBC-Proxy” with logging support. Its Maven-ready and comes with a easy Spring-integration. So how can we use this cool stuff … it is so easy:

1. Define the JDBCLogger dependencies in the pom.xml:


<dependencies>
<dependency>
 <groupId>net.sourceforge.jdbclogger</groupId>
 <artifactId>jdbclogger-core</artifactId>
 <version>0.7-SNAPSHOT</version>
 </dependency>
 <dependency>
 <groupId>net.sourceforge.jdbclogger</groupId>
 <artifactId>jdbclogger-spring</artifactId>
 <version>0.7-SNAPSHOT</version>
 </dependency>
 </dependencies>

The informations from the installation-guide on the project-site is a little too old, so the maven-repository http://jdbclogger.sourceforge.net/m2-repo/ doesn’t exists. No problem we can build jdbclogger-core and jdbclogger-spring by ourself (read more). The simplest way to build the two artifacts is:

  • checkout from  svn
  • edit master-pom, comment out all modules, leave only core and spring active
  • run mvn clean install from root-dir

2. Change your Spring-configuration, switch showSql off and add the following bean:


<bean id="jdbcLoggerConfig"
 class="net.sourceforge.jdbclogger.spring.JdbcLoggerBeanPostProcessor">
<property name="enabled" value="true" />
<property name="dataSourceConfigurations">
	<list>
 <bean class="net.sourceforge.jdbclogger.spring.JdbcLoggerDataSourceConfiguration">
<property name="dataSourceBeanName" value="dataSource" />
<property name="driverClassNamePropertyName" value="driverClassName" />
 </bean>
 </list>
 </property>
<property name="targetDriverClassNames">
	<list>
 <value>${jpa.driver}</value>
 </list>
 </property>
 </bean>

3.  Activate logging in the log4j.xml:


<category name="net.sourceforge.jdbclogger">
<priority value="debug" />
 </category>
<category name="net.sourceforge.jdbclogger.spring">
<priority value="error" />
 </category>

Thats it :-) Now you will see logmessages like this:

JdbcLoggerDriver:65 – Wrapper ‘net.sourceforge.jdbclogger.JdbcLoggerDriver’ successfully registed for driver ‘com.mysql.jdbc.Driver’
PreparedStatementWrapper:156 – Prepared Statement : select softwareca0_.id as id0_, softwareca0_.concurrentVersion as concurre2_0_, softwareca0_.CATEGORY_NAME as CATEGORY3_0_, softwareca0_.PARENT_ID as PARENT4_0_ from SoftwareCategory softwareca0_ where softwareca0_.PARENT_ID is null
StatementWrapper:45 – Statement : delete from softwarecategory_softwareobject
PreparedStatementWrapper:156 – Prepared Statement : insert into SoftwareCategory_SoftwareCategory (SoftwareCategory_id, POSITION, children_id) values (‘92′, ‘3′, ‘96′)

Speedup Release for Multiprojects with Maven

Tuesday, 5. May 2009 Andreas Höhmann Leave a comment

In huge multi-module-projects the maven-release-process might have a long running time because there is a lot of site-content to generate and to deployed (Of course this depends on the used report-plugins, i.e. javadoc, findbugs,pmd, dashboard etc.)

I noticed that the upload of the generated javadoc etc. uses a big amount of the deployment time. So how we can speedup this part of the deployment?

We can deploy the generated site in a local directory and after the successful release we can upload the whole directory to the server, i.e. zip the content and unpack on the server, or use a smb-shared-directory … then the site-upload is much faster than with site:deploy and webdav.


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<distributionManagement>
 <site>
 <id>site</id>
 <url>${site.distribution.url}/</url>
 </site>
<distributionManagement>
<profiles>
<profile>
 <id>release</id>
<properties>
 <site.distribution.url>file://D:/SITE-RELEASE/</site.distribution.url>
 <site.url>http://site-server/releases/</site.url>
 </properties>
 </profile>
</profiles>
<properties>
 <site.url>http://site-server/snapshots/</site.url>
 <site.distribution.url>dav:${site.url}</site.distribution.url>
</properties>

</project>

Try it :)

Realworld JSF Application Story

Monday, 27. April 2009 Andreas Höhmann Leave a comment

Vielleicht hatte ich es in einem früheren Posting schonmal erwähnt, ich arbeite momentan für Siemens an einem Web 2.0 Projekt und das ist jetzt fertig :D .

Los ging es November 2007 und nun konnten wir planmässig im April 2009 live gehen. Wir konnten dabei all die wunderbaren “neuen” Technologien einsetzen und ausprobieren, u.a. JSF und damit eine funktionsfähige (also den Anforderungen des Kunden voll entsprechende) und zugleich performante “Web 2.0″ Applikation bauen. Die Applikation nimmt sich dem Thema “Sicherheitstechnik” (für die Auskenner: ISO 13849-1 und IEC 62061) an.

Mal kurz zu den verwendeten “Technologien/Frameworks/Tools/Ideen”:

  • Daten ziehen wir aus einer SAP Knowledgebase (selbst gestrickt) und aus einer Datenbank via OpenJPA
  • Services/Manager sind “normale” Javaklassen (Stichwort Design-Pattern),
    als Kleber verwenden wir Spring (Stichwort Dependency Injection)
  • UI mit JBoss Richfaces (Stichwort Ajax), JSF + Facelets (Stichwort Xhtml-Template), jQuery, CSS, etc.
  • Buildsystem, Projektseiten mit Maven2
  • Continues Integration via TeamCity und Maven2
  • Tests hauptsächlich mit TestNG aber teilweise auch mit JUnit
  • Laden/Speichern von Benutzerdaten via XStream (FileupLoad via Tomahawk), das alles noch Versionskompatibel, d.h. selbsgestrickte XML-Transformationskette für DomainModell-Updates
  • PDF Reportgenerierung mit iText
  • Anbindung an Siemens “Single Sign On” System via Spring Security, Webservices

Im Rückblick kann ich sagen, dass eigentlich alles ohne größere Probleme miteinander funktioniert hat
… so soll es sein :D

https://www.automation.siemens.com/cd/safety/html_00/produkte/si_normen/tool.htm

(Für die Applikation muss man sich registrieren)

Hacking maven-eclipse-plugin with eclipse-ide

Sunday, 16. November 2008 Andreas Höhmann Leave a comment

This article show you how you can fix bugs for maven-plugins (eclipse setup for hacking the code, debugging etc.) with a concrete project: maven-eclipse-plugin. Lets start …

At the moment one of my private todos is to fix a classpath-bug for mavens eclipse-plugin.

First of all: this maven-plugin is great! If you have a maven-project and you want edit the source inside the eclipse-ide all you have to do is “mvn eclipse:eclipse” in the base-dir of the project. The plugin will generate all eclipse-files for you, e.g. “.project”, “.classpath”, the “.settings”-directory etc. And there is much more … e.g. pde-development with maven. Have a look at the plugin-homepage.

Ok. What’s the problem? I have a pom with more than one resources:

...
<build>
 <resources>
  <resource>
    <filtering>true</filtering>
    <directory>src/main/resources</directory>
    <includes>
     <include>**/*.properties</include>
    </includes>
  </resource>
  <resource>
    <filtering>false</filtering>
    <directory>src/main/resources</directory>
    <excludes>
     <exclude>**/*.properties</exclude>
    </excludes>
  </resource>
</resources>
</build>
...

The resources directory contains a lot of resources. For all property-files i want activate filtering, meens maven should replace placeholders in the files before the result is copied into the target-directory.

If i now start “mvn eclipse:eclipse” the plugin doesnt handle the different directories/includes/excludes correct. The result is a .classpath like this (i removed uninteresting entries).

<classpath>
 <classpathentry kind="src"
                 path="src/main/resources"
                 including="**/*.properties"
                 excluding="**/*.java"/>
</classpath>

Wrong buildpath

The second resource (with disabled filtering and the exlude for *.properties) was not included in the classpath. If the resource-directory contains other “important” files (e.g. spring-xmls for test or images or whatever) then the eclipse-environment is not complete.

The problem is now clear :) So lets fix the .classpath-generation-code. The plugin-code is available, maven can be started in debug-mode with “mvnDebug eclipse:eclipse” but then my first debug-session was not sucessful. I’m searching for the correct place to fix the code but where should i place a breakpoint? Mhhh … no sources for the maven-code … first of all i need a complete debugable maven-environment. To make a long story short … i got it :D Here is the todo-list:

  1. Use Eclipse and checkout maven-eclipse-plugin (Its a good idea to use the trunk – http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-eclipse-plugin).
  2. Now install the plugin with “mvn install”. This will install the newest version in the local repository.
  3. Then use “mvn eclipse:eclipse” to generate all eclipse-files for the maven-eclipse-plugin.
  4. Refresh the maven-eclipse-plugin project in the eclipse-ide. Now you are ready to debug a “mvn eclipse:eclipse” session. But hold a second! Most of the maven code will not be available in the ide, the debugging is not fun. To handle this you must checkout the maven-code.
  5. Use Eclipse and checkout the maven-sources (http://svn.apache.org/repos/asf/maven/components). There are many branches and tags available. Look into the pom.xml of the maven-eclipse-plugin to find out the right version. The plugin-api dependency is perfect for this:

        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-plugin-api</artifactId>
          <version>2.0.8</version>
        </dependency>
    

    So we have to checkout the 2.0.8 branch (http://svn.apache.org/repos/asf/maven/components/tags/maven-2.0.8).

  6. Now build maven with “mvn install” and prepare the usage in eclipse with “mvn eclipse:eclipse”.
  7. Create a working-set “maven 2.0.8″ and import all subprojects from the maven-project. With eclipse this is very ease. Use the “Existing Projects into Workspace” import. Select the base-directory of the maven-project and import all subprojects in the workspace. Important: you must delete the “.project” file in the maven-project-directory to run the bulk-import successfully!
  8. Now your workspace should look like this:
    Ready to hack maven-eclipse-plugin
  9. Now the last step – call “mvn eclipse:eclipse” for the maven-eclipse-pluigin project (second time). Then you will have a eclipse-project with project-dependencies to the maven-projects (e.g. maven-plugin-api).

The “eclipse-test” project contains the above pom.xml with the two resources.

To debug the eclipse-plugin i have to

  1. Start “mvnDebug eclipse:eclipse” in the eclipse-test project
  2. Start a “Remote Java Application” debug-session (localhost:8000) with additional sources of “maven-eclipse-plugin-trunk” project

NOW I’M READY TO FIX THE CODE :D

Show TeamCity Buildstatus in Maven Projectsite

Wednesday, 20. August 2008 Andreas Höhmann Comments off

Today i will show you a little hack for TeamCity and Maven. At the end you will be able to show the last (live!) buildstatus of your artifact on the generate project-site.

Lets define a new menu-item “status” in our project-site-descriptor (src/site/site.xml):

 ...
  <menu name="Overview" inherit="top">
  <item name="Introduction" href="index.html" />
  <item name="Status" href="status.html" />
  </menu>
 ...

Hint: you can do this in your parent-project, so all subproject will inherit this menu.

Now we must define the status.xml (src/site/xdoc/status.xml):

<?xml version="1.0" encoding="UTF-8"?>
<document>
  <properties>
    <title>Buildstatus</title>
  </properties>
  <body>
    <section name="Status">
      <div id="statuswidget"/>
    </section>
    <script type="text/javascript">
    <![CDATA[
      //
      // url to the team-city-server
      // define HOST, PORT and BUILDID
      //
      var url = 'http://HOST:PORT/externalStatus.html'
               + '?buildTypeId=BUILDID'
               + unescape( '%26' )   // "hide" amp
               + 'withCss=true';
      var container = document.getElementById('statuswidget');
      var iframe = document.createElement('iframe');
      iframe.style.width  = '100%';
      iframe.style.height = '500px';
      iframe.style.border = 'none';
      container.appendChild(iframe);
      iframe.doc = null;
      if(iframe.contentDocument)
        iframe.doc = iframe.contentDocument;
      else if(iframe.contentWindow)
        iframe.doc = iframe.contentWindow.document;
      else if(iframe.document)
        iframe.doc = iframe.document;
      iframe.doc.open();
      iframe.doc.close();
      iframe.doc.location.href=url;
    ]]>
    </script>
  </body>
</document>

Insert HOST and PORT. The BUILDID is the number of the build-configuration:

Hint: The width of the iframe should be 100% but you can customize the height – so if you later click on the status-element you can show teamcity directly in you projectsite … cool :D

Activate the status-widget for your build-configuration:

Build the site:

mvn clean site-deploy

Now you have a new menu-item, click and you will see the TeamCity status for your artifact.

The implementation details …

The “normal” way to display the build-status (see TeamCity documentation) is shown here:

<script type="text/javascript" src="<path_to_server>/externalStatus.html?js=1&amp;amp;buildTypeId=BUILDID">
</script>

But it’s not possible to insert this code in maven’s xdoc-format (there is no javascript-tag allowed!).
So i found a solution to insert the teamcity-url into a dynamic created iframe. The second trick is to encode the “&” in the url (unescape(‘%26′)).

Try it!