QcMylyn 0.2.7 is out!
The QC Mylyn Team proudly presents the 0.2.7 Release …
We need Feedback!
The QC Mylyn Team proudly presents the 0.2.7 Release …
We need Feedback!
The tool chain for building eclipse based applications with maven becomes better and better.
Read here.
I know 2 projects using maven to build eclipse plugins:
Which project are there else?
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

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

Try it
In my actual project i have to work in the employers office behind a firewall/proxy. The proxy requires a authentication so i have the following proxy-settings:

Since our development-team switch to eclipse 3.5. these settings don’t work anymore. We found out that the default http-client in eclipse 3.5. doesn’t support our proxy autentication. The solution was to exclude the “new” eclipse efc http-client via eclipse.ini:
-Dorg.eclipse.ecf.provider.filetransfer.excludeContributors=org.eclipse.ecf.provider.filetransfer.httpclient -Dhttp.proxyPort=8080 -Dhttp.proxyHost=proxyf.... -Dhttp.nonProxyHosts=localhost|127.0.0.1
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”:

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
/**
* 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:

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):

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

If anyone need the plugin … leave a comment.
Today i updated my Eclipse 3.5 M7 to the final 3.5. Here are my plugin list:

What are your prefered plugins?
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
http://download.eclipse.org/eclipse/downloads/drops/S-3.5M5-200902021535/eclipse-news-M5.html
Wird ja auch mal Zeit für Blockselektion:

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>
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
Here is the todo-list:
<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).
The “eclipse-test” project contains the above pom.xml with the two resources.
To debug the eclipse-plugin i have to
NOW I’M READY TO FIX THE CODE
Today i show how you can easily develop a Mavenproject with Spring-Beans
in your Eclipse-IDE. You have to add a new plugin to your pom’s
plugins-section:
...
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<projectNameTemplate>[artifactId]</projectNameTemplate>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<wtpmanifest>true</wtpmanifest>
<wtpapplicationxml>true</wtpapplicationxml>
<wtpversion>2.0</wtpversion>
<manifest>${basedir}/src/main/resources/META-INF/MANIFEST.MF</manifest>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<additionalConfig>
<file>
<name>.springBeans</name>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<configExtensions>
<configExtension>xml</configExtension>
</configExtensions>
<configs>
<config>src/main/resource/services.xml</config>
<config>src/main/resource/datasource.xml</config>
</configs>
<configSets>
<configSet>
<name>core</name>
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
<incomplete>false</incomplete>
<configs>
<config>src/main/resource/services.xml</config>
<config>src/main/resource/datasource.xml</config>
</configs>
</configSet>
</configSets>
</beansProjectDescription>]]>
</content>
</file>
<file>
<name>.settings/org.springframework.ide.eclipse.core.prefs</name>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8"?>
eclipse.preferences.version=1
org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true
org.springframework.ide.eclipse.core.enable.project.preferences=true
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=false
]]>
</content>
</file>
</additionalConfig>
</configuration>
</plugin>
</plugins>
</build>
...
Then you can run mvn eclipse:clean eclipse:eclipse (eclipse:clean is not required). The eclipse-plugin will create/change the .springBean and the .settings/org.springframework.ide.eclipse.core.prefs. Then you can refresh the eclipse-project (F5) from now the project contains a Spring-Builder which will handle the defined spring-configuration-files services.xml and datasource.xml. If you have more Springfiles you have to change the plugin-configuration.