<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Olaf&#039;s blog &#187; maven 2</title>
	<atom:link href="http://olafsblog.sysbsb.de/category/maven-2/feed/" rel="self" type="application/rss+xml" />
	<link>http://olafsblog.sysbsb.de</link>
	<description>Olaf&#039;s blog on software development and life</description>
	<lastBuildDate>Sat, 14 Aug 2010 20:39:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Testing SSL (HTTPS) clients with Junit and Jetty</title>
		<link>http://olafsblog.sysbsb.de/testing-ssl-https-clients-with-junit-and-jetty/</link>
		<comments>http://olafsblog.sysbsb.de/testing-ssl-https-clients-with-junit-and-jetty/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 07:54:17 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[unit test]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=124</guid>
		<description><![CDATA[I recently ran into a situation where a web service client had issues when invoking a webservice via HTTPS. To reproduce, I needed a lightweight, JUnit-based test to reproduce the problem and write a regression test. Here is how I got it to work:
First, I used the basic HTTP test setup. Now however, I needed [...]]]></description>
			<content:encoded><![CDATA[<p>I recently ran into a situation where a web service client had issues when invoking a webservice via HTTPS. To reproduce, I needed a lightweight, JUnit-based test to reproduce the problem and write a regression test. Here is how I got it to work:</p>
<p>First, I used the <a href="/lightweight-testing-of-webservice-http-clients-with-junit-and-jetty/">basic HTTP test setup</a>. Now however, I needed Jetty to provide a HTTPS connector. For this to work, Jetty &#8211; just like any other webserver, such as <a href="http://httpd.apache.org/docs/2.2/ssl/">apache</a> &#8211; needs a server certificate and a private key in a keystore. To create the keystore, I simply followed the excellent <a href="http://docs.codehaus.org/display/JETTY/How+to+configure+SSL">Jetty SSL guide</a>. Namingly, I did this (using Ubuntu, see the above link for alternatives):</p>
<pre>
openssl genrsa -des3 -out jetty.key
openssl req -new -x509 -key jetty.key -out jetty.crt
openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12
$JAVA_HOME/bin/keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore
</pre>
<p>Once I had the keystore set up, I placed it in the src/main/resources folder (the root of the classpath, in case you&#8217;re not a maven user) and extended the HttpTestServer like so:</p>
<pre class="brush: java;">
import java.net.URL;

import org.junit.Ignore;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.security.SslSocketConnector;

/**
 * A test server for testing SSL requests.
 *
 * @author Olaf Otto
 */
@Ignore
public class SslTestServer extends HttpTestServer {
	private static final int HTTPS_PORT = 50443;

	public SslTestServer() {
	}

	public SslTestServer(String mockData) {
		super(mockData);
	}

	@Override
	protected void configureServer() {
		super.configureServer();
		Connector secureConnector = createSecureConnector();
		getServer().addConnector(secureConnector);
	}

	private Connector createSecureConnector() {
		SslSocketConnector connector = new SslSocketConnector();
		connector.setPort(HTTPS_PORT);
		URL keystoreUrl = getClass().getClassLoader().getResource(&quot;keystore&quot;);
		connector.setKeystore(keystoreUrl.getFile());
		connector.setKeyPassword(&quot;test&quot;);
		return connector;
	}

	public static void main(String[] args) {
		SslTestServer server = new SslTestServer();
		try {
			server.start();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
</pre>
<p>(I added the @Ignore annotation as I placed the class in the test sources folder, though it&#8217;s not a test&#8230;)<br />
You might use it in your JUnit-based test like so:</p>
<pre class="brush: java;">
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * @author Olaf Otto
 */
public class MySslTest {
	private SslTestServer _server;

	@Before
	public void startServer() throws Exception {
		_server = new SslTestServer();
		_server.start();
	}

	@After
	public void stopServer() throws Exception {
		_server.stop();
	}

	@Test
	public void mySsltest() {
		_server.setMockResponseData(&quot;&lt;xml&gt;My client expects this response&lt;/xml&gt;&quot;);
		// Perform tests on port 50443...
	}
}
</pre>
<p>Here is <a href="http://olafsblog.sysbsb.de/wp-content/uploads/2010/07/https-testserver.zip">the whole package as a maven 2 project</a> (including the keystore with a self-signed certificate). Download, unzip, and give it a try (<code>mvn test</code>).</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/testing-ssl-https-clients-with-junit-and-jetty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lightweight testing of (webservice) HTTP clients with JUnit and Jetty</title>
		<link>http://olafsblog.sysbsb.de/lightweight-testing-of-webservice-http-clients-with-junit-and-jetty/</link>
		<comments>http://olafsblog.sysbsb.de/lightweight-testing-of-webservice-http-clients-with-junit-and-jetty/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 07:48:01 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[http clients]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[webservices]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=133</guid>
		<description><![CDATA[If you&#8217;re working with webservice clients you will certainly have noticed the complexity of integration-testing your webservice clients. Building webservice clients can already be quite a complex task, but providing a mock-up webservice backend delivering useful test responses is quite often just to much work, if not impossible, since many web service backends are very [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re working with webservice clients you will certainly have noticed the complexity of integration-testing your webservice clients. Building webservice clients can already be quite a complex task, but providing a mock-up webservice backend delivering useful test responses is quite often just to much work, if not impossible, since many web service backends are very complex constructs. Furthermore, setting up a backend for each integration test consumes valuable build time.</p>
<p>As an alternative, one may simply replace the backend with a mock HTTP server that does one thing: deliver the <em>expected webserver response</em> &#8211; i.e. XML data  &#8211; when called by the client. All you need to set this up is a HTTP server and a pre-recorded service response (quite often this comes with WS client specifications). If you don&#8217;t have this data, you can record it, for example using a proxy server in between your WS client and a real WS backend, or a tool such as <a href="http://www.wireshark.org/">wireshark</a>.</p>
<p>The recorded XML response thus represents your assumptions against which you test the client. This makes your tests fast, lightweight and a lot better to understand. </p>
<p>Here is my Jetty-based test HTTP server:</p>
<pre class="brush: java;">
package de.sysbsb.test;

import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.apache.commons.io.IOUtils.write;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.junit.Ignore;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.HttpConnection;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.AbstractHandler;

/**
 * A server for answering HTTP requests with test response data.
 *
 * @author Olaf Otto
 */
@Ignore
public class HttpTestServer {
	public static final int HTTP_PORT = 50036;

	private Server _server;
	private String _responseBody;
	private String _requestBody;
	private String _mockResponseData;

	public HttpTestServer() {
	}

	public HttpTestServer(String mockData) {
		setMockResponseData(mockData);
	}

	public void start() throws Exception {
		configureServer();
		startServer();
	}

	private void startServer() throws Exception {
		_server.start();
	}

	protected void configureServer() {
		_server = new Server(HTTP_PORT);
		_server.setHandler(getMockHandler());
	}

	/**
	 * Creates an {@link AbstractHandler handler} returning an arbitrary String as a response.
	 *
	 * @return never &lt;code&gt;null&lt;/code&gt;.
	 */
	public Handler getMockHandler() {
		Handler handler = new AbstractHandler() {

			public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException {
				Request baseRequest = request instanceof Request ? (Request) request : HttpConnection.getCurrentConnection().getRequest();
				setResponseBody(getMockResponseData());
				setRequestBody(IOUtils.toString(baseRequest.getInputStream()));
				response.setStatus(SC_OK);
				response.setContentType(&quot;text/xml;charset=utf-8&quot;);
				write(getResponseBody(), response.getOutputStream());
				baseRequest.setHandled(true);
			}
		};
		return handler;
	}

	public void stop() throws Exception {
		_server.stop();
	}

	public void setResponseBody(String responseBody) {
		_responseBody = responseBody;
	}

	public String getResponseBody() {
		return _responseBody;
	}

	public void setRequestBody(String requestBody) {
		_requestBody = requestBody;
	}

	public String getRequestBody() {
		return _requestBody;
	}

	public static void main(String[] args) {
		HttpTestServer server = new HttpTestServer();
		try {
			server.start();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public void setMockResponseData(String mockResponseData) {
		_mockResponseData = mockResponseData;
	}

	public String getMockResponseData() {
		return _mockResponseData;
	}

	protected Server getServer() {
		return _server;
	}
}
</pre>
<p>You can use it in a JUnit test like so:</p>
<pre class="brush: java;">
package de.sysbsb.test;

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * @author Olaf Otto
 */
public class MyClientTest {
	private HttpTestServer _server;

	@Before
	public void startTestServer() throws Exception {
		_server = new HttpTestServer();
		_server.start();
	}

	@After
	public void stopTestServer() throws Exception {
		_server.stop();
	}

	@Test
	public void someClientTest() throws IOException {
		_server.setMockResponseData(&quot;&lt;xml&gt;&lt;testdata&gt;hello, world&lt;/testdata&gt;&lt;/xml&gt;&quot;);
		// or as a much more elegant alternative:
		_server.setMockResponseData(getRecordedResponse(&quot;testdata.xml&quot;));
		// run your client tests, using the HttpTestServer.HTTP_PORT
	}

	private String getRecordedResponse(String recordedResponseFile) throws IOException {
		InputStream testDataStream = getClass().getClassLoader().getResourceAsStream(recordedResponseFile);
		return IOUtils.toString(testDataStream);
	}
}
</pre>
<p><a href="http://olafsblog.sysbsb.de/wp-content/uploads/2010/07/http-testserver.zip">Here are is the HTTP test server and a JUnit test example as a maven 2 project</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/lightweight-testing-of-webservice-http-clients-with-junit-and-jetty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Per-assembly filtering with the maven-assembly-plugin</title>
		<link>http://olafsblog.sysbsb.de/per-assembly-filtering-with-the-maven-assembly-plugin/</link>
		<comments>http://olafsblog.sysbsb.de/per-assembly-filtering-with-the-maven-assembly-plugin/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 10:50:00 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[maven 2]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">https://olafsblog.sysbsb.de/?p=82</guid>
		<description><![CDATA[The maven assembly plugin is an extremely powerful tool when it comes to creating custom distributions (aka assemblies) of your artifacts for individual platforms etc. However, the ability to create multiple variants of an artifact within a single build conflicts with the standard maven approach of using multiple build profiles and executing a single build [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://maven.apache.org/plugins/maven-assembly-plugin/">maven assembly plugin</a> is an extremely powerful tool when it comes to creating custom distributions (aka assemblies) of your artifacts for individual platforms etc. However, the ability to create multiple variants of an artifact within a single build conflicts with the <a href="http://maven.apache.org/guides/mini/guide-building-for-different-environments.html">standard maven approach of using multiple build profiles and executing a single build for each profile to generate artifact variants</a>.</p>
<p>This also means that <a href="http://www.sonatype.com/books/mvnref-book/reference/resource-filtering.html">mavens resource filtering</a> is not very useful for individual assemblies, since you can only replace placeholders such as ${someValue} with the same value for all assemblies (since resources are only filtered once, using the active profile(s), for all assemblies).</p>
<p>You can, however, configure the maven assembly plugin to use individual filter property files for each assembly using the <code>&lt;execution&gt;</code> section of the plugin configuration, like so:</p>
<pre class="brush: xml">
&lt;plugin&gt;
  &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;

  &lt;version&gt;2.2-beta-5&lt;/version&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;id&gt;production&lt;/id&gt;
      &lt;goals&gt;

        &lt;goal&gt;single&lt;/goal&gt;
      &lt;/goals&gt;
      &lt;configuration&gt;
        &lt;filters&gt;
          &lt;filter&gt;${project.basedir}/src/main/assembly/production.properties&lt;/filter&gt;

        &lt;/filters&gt;
        &lt;finalName&gt;${artifactId}-production-${version}&lt;/finalName&gt;
        &lt;ignoreDirFormatExtensions&gt;true&lt;/ignoreDirFormatExtensions&gt;
        &lt;descriptors&gt;
          &lt;descriptor&gt;src/main/assembly/assembly.xml&lt;/descriptor&gt;

        &lt;/descriptors&gt;
      &lt;/configuration&gt;
      &lt;phase&gt;package&lt;/phase&gt;
    &lt;/execution&gt;
    &lt;execution&gt;

      &lt;id&gt;integration&lt;/id&gt;
      &lt;goals&gt;
        &lt;goal&gt;single&lt;/goal&gt;
      &lt;/goals&gt;
      &lt;configuration&gt;

        &lt;filters&gt;
          &lt;filter&gt;${project.basedir}/src/main/assembly/integration.properties&lt;/filter&gt;
        &lt;/filters&gt;
        &lt;finalName&gt;${artifactId}-integration-${version}&lt;/finalName&gt;
        &lt;ignoreDirFormatExtensions&gt;true&lt;/ignoreDirFormatExtensions&gt;

        &lt;descriptors&gt;
          &lt;descriptor&gt;src/main/assembly/assembly.xml&lt;/descriptor&gt;
        &lt;/descriptors&gt;
      &lt;/configuration&gt;
      &lt;phase&gt;package&lt;/phase&gt;

    &lt;/execution&gt;
  &lt;/executions&gt;
&lt;/plugin&gt;
</pre>
<p>This snippet uses the same assembly descriptor (you can use any assembly descriptor, actually) to build individual artifacts for production and integration. Note that the <code>${project.basedir}/</code> prefix is a workaround for <a href="http://jira.codehaus.org/browse/MASSEMBLY-150">MASSEMBLY-150</a> and is nedded to avoid a nasty <code>Failed to create assembly: Error filtering file ... Error loading property file 'src/main/...'</code> error when executing the mojo from outside the module directory (say, for instance, in a mvn release:prepare&#8230;).</p>
<p>Filtering must be enabled in the assembly descriptor, like so:</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;assembly xmlns=&quot;http://maven.apache.org/xsd/assembly&quot;
  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;

  xsi:schemaLocation=&quot;http://maven.apache.org/xsd/assembly http://maven.apache.org/xsd/assembly-1.1.1.xsd&quot;&gt;
  ...
  &lt;fileSets&gt;
    &lt;fileSet&gt;
      &lt;filtered&gt;true&lt;/filtered&gt;
      ...
    &lt;/fileSet&gt;

  &lt;/fileSets&gt;
&lt;/assembly&gt;
</pre>
<p>Thanks to John Casey for suggesting this in <a href="http://jira.codehaus.org/browse/MASSEMBLY-430">MASSEMBLY-430</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/per-assembly-filtering-with-the-maven-assembly-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running mvn:release with Subversion 1.5.x</title>
		<link>http://olafsblog.sysbsb.de/running-mvnrelease-with-subversion-15x/</link>
		<comments>http://olafsblog.sysbsb.de/running-mvnrelease-with-subversion-15x/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 16:26:22 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[SCM]]></category>
		<category><![CDATA[System engineering]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=73</guid>
		<description><![CDATA[When attempting to prepare a release using maven and the maven-release-plugin, you are currently very likely to see your build fail with a message such as:

[INFO] Executing: svn --non-interactive copy --file /tmp/...commit . https://subversion..../tags/...
[INFO] Working directory: ...
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Unable to tag SCM
Provider message:
The svn tag command failed.
Command output:
svn: Commit failed (details follow):
svn: [...]]]></description>
			<content:encoded><![CDATA[<p>When attempting to prepare a release using maven and the <a href="http://maven.apache.org/plugins/maven-release-plugin/">maven-release-plugin</a>, you are currently very likely to see your build fail with a message such as:</p>
<p><code><br />
[INFO] Executing: svn --non-interactive copy --file /tmp/...commit . https://subversion..../tags/...<br />
[INFO] Working directory: ...<br />
[INFO] ------------------------------------------------------------------------<br />
[ERROR] BUILD FAILURE<br />
[INFO] ------------------------------------------------------------------------<br />
[INFO] Unable to tag SCM<br />
Provider message:<br />
The svn tag command failed.<br />
Command output:<br />
svn: Commit failed (details follow):<br />
svn: File '...' already exists<br />
</code></p>
<p>If you do, you are using subversion 1.5.x which no longer supports tagging from a local working copy, thus causing the unfortunately very misleading error message.</p>
<p>This is a <a href="http://jira.codehaus.org/browse/SCM-406"> known issue of the subversion sourcecode management  (SCM)</a> and there is a simple workaround:<br />
<span id="more-73"></span><br />
Use the latest 2.x snapshot version of the maven release plugin and configure it to use remote tagging (on the subversion server) rather than tagging from your local copy.</p>
<p>You can do so by </p>
<h3>1.) Adding the apache snapshots repository to your plugin repositories list</h3>
<pre class="brush: xml;">
    &lt;pluginRepositories&gt;
        &lt;pluginRepository&gt;
            &lt;id&gt;apache-snapshots&lt;/id&gt;
            &lt;name&gt;Apache Snapshot Repository&lt;/name&gt;
            &lt;url&gt;http://repository.apache.org/snapshots/&lt;/url&gt;
            &lt;snapshots&gt;
                &lt;enabled&gt;true&lt;/enabled&gt;
            &lt;/snapshots&gt;
        &lt;/pluginRepository&gt;
        ...
    &lt;/pluginRepositories&gt;
</pre>
<h3>2.) Configuring the release plugin&#8217;s version and tagging</h3>
<pre class="brush: xml;">
        ...
        &lt;build&gt;
        ...
        &lt;pluginManagement&gt;
            &lt;plugins&gt;
                &lt;plugin&gt;
                    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                    &lt;artifactId&gt;maven-release-plugin&lt;/artifactId&gt;
                    &lt;version&gt;2.0-beta-9-SNAPSHOT&lt;/version&gt;
                    &lt;configuration&gt;
                        &lt;tagBase&gt;full url to the tags directory on the svn server&lt;/tagBase&gt;
                        &lt;!-- See http://jira.codehaus.org/browse/SCM-406 --&gt;
                        &lt;remoteTagging&gt;true&lt;/remoteTagging&gt;
                        &lt;!-- Further non-mandatory but useful settings... --&gt;
                        &lt;preparationGoals&gt;clean install&lt;/preparationGoals&gt;
                        &lt;autoVersionSubmodules&gt;true&lt;/autoVersionSubmodules&gt;
                    &lt;/configuration&gt;
                &lt;/plugin&gt;
            &lt;/plugins&gt;
        &lt;/pluginManagement&gt;
        ...
        &lt;/build&gt;
        ...
</pre>
<p>This fixed it for me.</p>
<p>Note: i had problems getting this to function with the scp:// protocol (provider) for my distribution repository. It seems logic, tough, that the choosen provider must support remote tagging, thus i choose the scpexe:// protocol (using a local scp executable) instead, that worked:</p>
<pre class="brush: xml;">
...
&lt;distributionManagement&gt;
&lt;repository&gt;
  &lt;id&gt;myReo&lt;/id&gt;
  &lt;name&gt;myreo&lt;/name&gt;
  &lt;url&gt;scpexe://...&lt;/url&gt;
 &lt;/repository&gt;
...
&lt;/distributionManagement&gt;
...
</pre>
<p>Apparently, the upcoming 2.0 release of the maven-release-plugin will have remote tagging as default, so if you read this and the 2.0 version has been released, simply using it should do the job.</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/running-mvnrelease-with-subversion-15x/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Maven, Surefire, remote debugging and the -javaagent switch</title>
		<link>http://olafsblog.sysbsb.de/maven-surefire-remote-debugging-and-the-javaagent-switch/</link>
		<comments>http://olafsblog.sysbsb.de/maven-surefire-remote-debugging-and-the-javaagent-switch/#comments</comments>
		<pubDate>Mon, 02 Feb 2009 12:31:17 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=70</guid>
		<description><![CDATA[When using maven surefire in conjunction with remote debugging (mvnDebug, for instance)
it seems necessary to disable forking of the test executions into separate processes, as the remote debugging works process wise. This is usually done by setting the the fork mode to never, e.g. by specifying -DforkMode=never on the command line.
This is, however, a misunderstanding. [...]]]></description>
			<content:encoded><![CDATA[<p>When using <a href="http://maven.apache.org/plugins/maven-surefire-plugin/">maven surefire</a> in conjunction with remote debugging (<code>mvnDebug</code>, for instance)<br />
it seems necessary to disable forking of the test executions into separate processes, as the remote debugging works process wise. This is usually done by setting the the fork mode to never, e.g. by specifying <code>-DforkMode=never</code> on the command line.</p>
<p>This is, however, a misunderstanding. mvnDebug is there to <em>enable debugging of the maven process</em> and not of the surefire execution &#8211; and disabling forking may have various side effects. One of those is the use of Java agents. When using agents, e.g. for <a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-aj-ltw">loadtime-weaving in the Spring Framework</a>, one often specifies a <code>-javaagent:</code> as a JVM argument for surefire:<br />
<span id="more-70"></span></p>
<pre class="brush: xml;">
&lt;!-- See http://maven.apache.org/plugins/maven-surefire-plugin/ --&gt;
	&lt;plugin&gt;
	&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
	&lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
	&lt;configuration&gt;
		&lt;!--
			The following must be within one line of code, line breaks will
			cause surefire execution to fail.
		--&gt;
		&lt;argLine&gt;-javaagent:/path/to/myagent.jar&lt;/argLine&gt;
	&lt;/configuration&gt;
</pre>
<p>Java agents however <em>must be provided as an argument to the JVM when it starts</em> &#8211; which is exactly what happens when surefire &#8220;forks&#8221;.<br />
Thus: No forking, no agents, since the tests will be executed in the current jvm used to execute maven itself &#8211; and that one was not started with a -javaagent argument. In order to execute  surefire tests and use agents, the forkMode must at least be &#8220;once&#8221; (<code>-DforkMode=once</code>).</p>
<p>Thus, leave the forking as it is, and <a href="http://maven.apache.org/plugins/maven-surefire-plugin/examples/debugging.html">enable remote debugging as described in the surefire plug-in documentation</a>, i.e. without using mvnDebug:</p>
<p><code><br />
mvn test -Dmaven.surefire.debug<br />
</code></p>
<p>Which will open a remote debugging port at localhost:5005 for the test execution &#8211; and use the agents.</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/maven-surefire-remote-debugging-and-the-javaagent-switch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Repository search for maven artifacts</title>
		<link>http://olafsblog.sysbsb.de/repository-search-for-maven-artifacts/</link>
		<comments>http://olafsblog.sysbsb.de/repository-search-for-maven-artifacts/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 10:33:13 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=69</guid>
		<description><![CDATA[Most of the maven users know the site www.mvnrepository.com which provides a nice lookup of maven artefacts.
Now there is also a newer site, www.mvnbrowser.com which currently performs better than mvnrepository. In addition, you can lookup repositories actually containing your desired artifact &#8211; now that&#8217;s sweet!
]]></description>
			<content:encoded><![CDATA[<p>Most of the maven users know the site <a href="http://www.mvnrepository.com">www.mvnrepository.com</a> which provides a nice lookup of maven artefacts.<br />
Now there is also a newer site, <a href="http://www.mvnbrowser.com">www.mvnbrowser.com</a> which currently performs better than mvnrepository. In addition, you can lookup repositories actually containing your desired artifact &#8211; now that&#8217;s sweet!</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/repository-search-for-maven-artifacts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>OutOfMemoryError using findbugs &amp; continuum &#8211; and how to fix it.</title>
		<link>http://olafsblog.sysbsb.de/outofmemoryerror-using-findbugs-continuum-and-how-to-fix-it/</link>
		<comments>http://olafsblog.sysbsb.de/outofmemoryerror-using-findbugs-continuum-and-how-to-fix-it/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 00:04:35 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[continuum]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=46</guid>
		<description><![CDATA[When using findbugs through the findbugs maven plugin, one is very likely to see the maven build in continuum fail with an OutOfMemory-Exception like this:


java.lang.OutOfMemoryError: Java heap space
	at java.util.ArrayList.&#60;init&#62;(ArrayList.java:112)
	at edu.umd.cs.findbugs.ba.Frame.&#60;init&#62;(Frame.java:111)
	at edu.umd.cs.findbugs.ba.vna.ValueNumberFrame.&#60;init&#62;(ValueNumberFrame.java:55)
	at edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis.createFact(ValueNumberAnalysis.java:131)
	at edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis.createFact(ValueNumberAnalysis.java:56)
	at edu.umd.cs.findbugs.ba.BasicAbstractDataflowAnalysis.lookupOrCreateFact(BasicAbstractDataflowAnalysis.java:171)
	at edu.umd.cs.findbugs.ba.BasicAbstractDataflowAnalysis.getResultFact(BasicAbstractDataflowAnalysis.java:73)
	at edu.umd.cs.findbugs.ba.Dataflow.&#60;init&#62;(Dataflow.java:78)
	at edu.umd.cs.findbugs.ba.AbstractDataflow.&#60;init&#62;(AbstractDataflow.java:42)
	at edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow.&#60;init&#62;(ValueNumberDataflow.java:34)
	at edu.umd.cs.findbugs.ba.ClassContext$3.analyze(ClassContext.java:611)
	at edu.umd.cs.findbugs.ba.ClassContext$3.analyze(ClassContext.java:599)
	at edu.umd.cs.findbugs.ba.ClassContext$AnalysisFactory.getAnalysis(ClassContext.java:266)
	at edu.umd.cs.findbugs.ba.ClassContext.getValueNumberDataflow(ClassContext.java:1376)
	at edu.umd.cs.findbugs.detect.BuildUnconditionalParamDerefDatabase.analyzeMethod(BuildUnconditionalParamDerefDatabase.java:96)
	at edu.umd.cs.findbugs.detect.BuildUnconditionalParamDerefDatabase.considerMethod(BuildUnconditionalParamDerefDatabase.java:85)
	at edu.umd.cs.findbugs.detect.BuildUnconditionalParamDerefDatabase.visitClassContext(BuildUnconditionalParamDerefDatabase.java:71)
	at edu.umd.cs.findbugs.DetectorToDetector2Adapter.visitClass(DetectorToDetector2Adapter.java:64)
	at edu.umd.cs.findbugs.FindBugs2.analyzeApplication(FindBugs2.java:658)
	at edu.umd.cs.findbugs.FindBugs2.execute(FindBugs2.java:185)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:52)
	at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:714)
	at [...]]]></description>
			<content:encoded><![CDATA[<p>When using <a href="http://findbugs.sourceforge.net">findbugs</a> through the <a href="http://mojo.codehaus.org/findbugs-maven-plugin/">findbugs maven plugin</a>, one is very likely to see the maven build in <a href="http://continuum.apache.org/">continuum</a> fail with an OutOfMemory-Exception like this:<br />
<span id="more-46"></span><br />
<code><br />
java.lang.OutOfMemoryError: Java heap space<br />
	at java.util.ArrayList.&lt;init&gt;(ArrayList.java:112)<br />
	at edu.umd.cs.findbugs.ba.Frame.&lt;init&gt;(Frame.java:111)<br />
	at edu.umd.cs.findbugs.ba.vna.ValueNumberFrame.&lt;init&gt;(ValueNumberFrame.java:55)<br />
	at edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis.createFact(ValueNumberAnalysis.java:131)<br />
	at edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis.createFact(ValueNumberAnalysis.java:56)<br />
	at edu.umd.cs.findbugs.ba.BasicAbstractDataflowAnalysis.lookupOrCreateFact(BasicAbstractDataflowAnalysis.java:171)<br />
	at edu.umd.cs.findbugs.ba.BasicAbstractDataflowAnalysis.getResultFact(BasicAbstractDataflowAnalysis.java:73)<br />
	at edu.umd.cs.findbugs.ba.Dataflow.&lt;init&gt;(Dataflow.java:78)<br />
	at edu.umd.cs.findbugs.ba.AbstractDataflow.&lt;init&gt;(AbstractDataflow.java:42)<br />
	at edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow.&lt;init&gt;(ValueNumberDataflow.java:34)<br />
	at edu.umd.cs.findbugs.ba.ClassContext$3.analyze(ClassContext.java:611)<br />
	at edu.umd.cs.findbugs.ba.ClassContext$3.analyze(ClassContext.java:599)<br />
	at edu.umd.cs.findbugs.ba.ClassContext$AnalysisFactory.getAnalysis(ClassContext.java:266)<br />
	at edu.umd.cs.findbugs.ba.ClassContext.getValueNumberDataflow(ClassContext.java:1376)<br />
	at edu.umd.cs.findbugs.detect.BuildUnconditionalParamDerefDatabase.analyzeMethod(BuildUnconditionalParamDerefDatabase.java:96)<br />
	at edu.umd.cs.findbugs.detect.BuildUnconditionalParamDerefDatabase.considerMethod(BuildUnconditionalParamDerefDatabase.java:85)<br />
	at edu.umd.cs.findbugs.detect.BuildUnconditionalParamDerefDatabase.visitClassContext(BuildUnconditionalParamDerefDatabase.java:71)<br />
	at edu.umd.cs.findbugs.DetectorToDetector2Adapter.visitClass(DetectorToDetector2Adapter.java:64)<br />
	at edu.umd.cs.findbugs.FindBugs2.analyzeApplication(FindBugs2.java:658)<br />
	at edu.umd.cs.findbugs.FindBugs2.execute(FindBugs2.java:185)<br />
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br />
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br />
	at java.lang.reflect.Method.invoke(Method.java:597)<br />
	at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:52)<br />
	at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:714)<br />
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:583)<br />
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:476)<br />
	at org.codehaus.groovy.runtime.Invoker.invokePogoMethod(Invoker.java:115)<br />
	at org.codehaus.groovy.runtime.Invoker.invokeMethod(Invoker.java:81)<br />
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:85)<br />
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:158)<br />
</code></p>
<p>This is not because continuum lacks memory, but because maven does &#8211; and running findbugs is a quite resource-hungry undertaking.<br />
The following addition to the &#8220;mvn&#8221; executable (residing in your maven&#8217;s &#8220;bin&#8221; folder) should do (tested in the 2.0.8 release):</p>
<p><code>MAVEN_OPTS="-Xmx1024m -Xms128m -XX:MaxPermSize=512m"</code>.</p>
<p>I must admit that <code>-Xmx1024m</code> is rather generous, though. 256m or 512m might do for many cases, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/outofmemoryerror-using-findbugs-continuum-and-how-to-fix-it/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ContinuumBuildCancelledException in continuum</title>
		<link>http://olafsblog.sysbsb.de/continuumbuildcancelledexception-in-continuum/</link>
		<comments>http://olafsblog.sysbsb.de/continuumbuildcancelledexception-in-continuum/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 23:48:12 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[continuum]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=44</guid>
		<description><![CDATA[Users of continuum might see their builds fail with the following exception when running a little more voluminous build:

org.apache.maven.continuum.execution.ContinuumBuildCancelledException: The build was cancelled

	at org.apache.maven.continuum.execution.AbstractBuildExecutor.executeShellCommand(AbstractBuildExecutor.java:214)
	at org.apache.maven.continuum.execution.maven.m2.MavenTwoBuildExecutor.build(MavenTwoBuildExecutor.java:138)
	at org.apache.maven.continuum.core.action.ExecuteBuilderContinuumAction.execute(ExecuteBuilderContinuumAction.java:118)
	at org.apache.maven.continuum.buildcontroller.DefaultBuildController.performAction(DefaultBuildController.java:408)
	at org.apache.maven.continuum.buildcontroller.DefaultBuildController.build(DefaultBuildController.java:147)
	at org.apache.maven.continuum.buildcontroller.BuildProjectTaskExecutor.executeTask(BuildProjectTaskExecutor.java:50)
	at org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor$ExecutorRunnable$1.run(ThreadedTaskQueueExecutor.java:116)
	at edu.emory.mathcs.backport.java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
	at edu.emory.mathcs.backport.java.util.concurrent.FutureTask.run(FutureTask.java:176)
	at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:987)
	at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:528)
	at java.lang.Thread.run(Thread.java:619)
Caused by: org.codehaus.plexus.util.cli.CommandLineException: Error while executing external command, process killed.
	at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:164)
	at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:89)
	at org.apache.maven.continuum.utils.shell.DefaultShellCommandHelper.executeShellCommand(DefaultShellCommandHelper.java:114)
	at org.apache.maven.continuum.utils.shell.DefaultShellCommandHelper.executeShellCommand(DefaultShellCommandHelper.java:59)
	at org.apache.maven.continuum.execution.AbstractBuildExecutor.executeShellCommand(AbstractBuildExecutor.java:202)
	... 11 more
Caused by: java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at [...]]]></description>
			<content:encoded><![CDATA[<p>Users of <a href="http://continuum.apache.org/">continuum</a> might see their builds fail with the following exception when running a little more voluminous build:</p>
<p><code><br />
org.apache.maven.continuum.execution.ContinuumBuildCancelledException: The build was cancelled<br />
<span id="more-44"></span><br />
	at org.apache.maven.continuum.execution.AbstractBuildExecutor.executeShellCommand(AbstractBuildExecutor.java:214)<br />
	at org.apache.maven.continuum.execution.maven.m2.MavenTwoBuildExecutor.build(MavenTwoBuildExecutor.java:138)<br />
	at org.apache.maven.continuum.core.action.ExecuteBuilderContinuumAction.execute(ExecuteBuilderContinuumAction.java:118)<br />
	at org.apache.maven.continuum.buildcontroller.DefaultBuildController.performAction(DefaultBuildController.java:408)<br />
	at org.apache.maven.continuum.buildcontroller.DefaultBuildController.build(DefaultBuildController.java:147)<br />
	at org.apache.maven.continuum.buildcontroller.BuildProjectTaskExecutor.executeTask(BuildProjectTaskExecutor.java:50)<br />
	at org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor$ExecutorRunnable$1.run(ThreadedTaskQueueExecutor.java:116)<br />
	at edu.emory.mathcs.backport.java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)<br />
	at edu.emory.mathcs.backport.java.util.concurrent.FutureTask.run(FutureTask.java:176)<br />
	at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:987)<br />
	at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:528)<br />
	at java.lang.Thread.run(Thread.java:619)<br />
Caused by: org.codehaus.plexus.util.cli.CommandLineException: Error while executing external command, process killed.<br />
	at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:164)<br />
	at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:89)<br />
	at org.apache.maven.continuum.utils.shell.DefaultShellCommandHelper.executeShellCommand(DefaultShellCommandHelper.java:114)<br />
	at org.apache.maven.continuum.utils.shell.DefaultShellCommandHelper.executeShellCommand(DefaultShellCommandHelper.java:59)<br />
	at org.apache.maven.continuum.execution.AbstractBuildExecutor.executeShellCommand(AbstractBuildExecutor.java:202)<br />
	... 11 more<br />
Caused by: java.lang.InterruptedException<br />
	at java.lang.Object.wait(Native Method)<br />
	at java.lang.Object.wait(Object.java:485)<br />
	at java.lang.UNIXProcess.waitFor(UNIXProcess.java:165)<br />
	at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:128)<br />
	... 15 more<br />
</code></p>
<p>The simple reason is: The build is taking longer than continuum allows it to take, and thus the execution is canceled.<br />
The maximum amount of time a build may take is schedule-specific, and can thus be configured in the &#8220;schedules&#8221; view under &#8220;Administration&#8221;.</p>
<p>If you change the execution time, i would recommend to adapt the time between checks for new builds accordingly.</p>
<p>Here&#8217;s a screenshot showing the setting that worked for my maven project:</p>
<p><img id="image43" src="http://olafsblog.sysbsb.de/wp-content/uploads/2008/04/continuum-edit-schedule.png" alt="Continuum: Edit schedule" /></p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/continuumbuildcancelledexception-in-continuum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring custom username for maven&#8217;s scm with subversion and ssh</title>
		<link>http://olafsblog.sysbsb.de/configuring-custom-username-for-mavens-scm-with-subversion-and-ssh/</link>
		<comments>http://olafsblog.sysbsb.de/configuring-custom-username-for-mavens-scm-with-subversion-and-ssh/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 23:25:57 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[System engineering]]></category>
		<category><![CDATA[continuum]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=42</guid>
		<description><![CDATA[I just stumbled over a nice little problem: When using the maven 2 changelog plugin, it automatically uses the configured &#60;scm&#62; settings and attempts to fetch the change history with them.
Unfortunately, such a setting usually does not contain a username, since this has to be provided by the actual team member connecting to version control.
Neither [...]]]></description>
			<content:encoded><![CDATA[<p>I just stumbled over a nice little problem: When using the <a href="http://maven.apache.org/plugins/maven-changelog-plugin/">maven 2 changelog plugin</a>, it automatically uses the configured &lt;scm&gt; settings and attempts to fetch the change history with them.</p>
<p>Unfortunately, such a setting usually does not contain a username, since this has to be provided by the actual team member connecting to version control.<br />
Neither did i have any intention to configure a placeholder into the scm section, forcing the developers to mess with the maven settings.xml in order to provide their own username.</p>
<p>Luckily, after searching a while, i found a proper solution.<br />
SSH allows an optional per-host specific username setting to be placed in a file called &#8220;config&#8221; located in the user&#8217;s .ssh directory, for example</p>
<p>File: ~/.ssh/config</p>
<p><code><br />
Host my.host.name<br />
User myusername<br />
</code></p>
<p>Thanks to <a href="http://programmingishard.com/users/spicycode">Chad Humphries</a>  for posting <a href="http://programmingishard.com/code/434">the Solution on programming is hard</a>.<br />
It really wasn&#8217;t&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/configuring-custom-username-for-mavens-scm-with-subversion-and-ssh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>maven autocompletion für die shell (und windows)</title>
		<link>http://olafsblog.sysbsb.de/maven-autocompletion-fur-die-shell-und-windows/</link>
		<comments>http://olafsblog.sysbsb.de/maven-autocompletion-fur-die-shell-und-windows/#comments</comments>
		<pubDate>Wed, 26 Mar 2008 13:23:09 +0000</pubDate>
		<dc:creator>olaf</dc:creator>
				<category><![CDATA[System engineering]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://olafsblog.sysbsb.de/?p=34</guid>
		<description><![CDATA[Beim Arbeiten mit maven stört die fehlende automatische Vervollständigung auf der Kommadozeile, insbesondere wenn man den Komfort einer ordentlichen unix-shell gewähnt ist. Doch dem kann abgeholfen werden. Aktuelle Linux-Distributionen (und unter Windows CYGWIN) besitzen mit bash-completion eine einfache Schnittstelle zum Erweitern der Autocompletion.

mvn-Vervollständigung unter Ubuntu 7.10 (Gutsy Gibbon)
Unter der ubuntu-Distribution 7.10 (Gutsy Gibbon) aktiviert man [...]]]></description>
			<content:encoded><![CDATA[<p>Beim Arbeiten mit <a href="http://maven.apache.org">maven</a> stört die fehlende automatische Vervollständigung auf der Kommadozeile, insbesondere wenn man den Komfort einer ordentlichen unix-shell gewähnt ist. Doch dem kann abgeholfen werden. Aktuelle Linux-Distributionen (und unter Windows <a href="http://www.cygwin.com/">CYGWIN</a>) besitzen mit bash-completion eine einfache Schnittstelle zum Erweitern der Autocompletion.<br />
<span id="more-34"></span></p>
<h3>mvn-Vervollständigung unter Ubuntu 7.10 (Gutsy Gibbon)</h3>
<p>Unter der <a href="http://wiki.ubuntuusers.de/Gutsy_Gibbon">ubuntu-Distribution 7.10 (Gutsy Gibbon)</a> aktiviert man die autocompletion durch Anlegen einer completion-Datei im Verzeichnis <code>/etc/bash_completion.d</code>, beispielsweise mit folgenden Inhalt:</p>
<pre class="brush: php;">
#!/bin/bash

_m2_make_goals()
{
  plugin=$1
  mojos=$2
  for mojo in $mojos
  do
    export goals=&quot;$goals $plugin:$mojo&quot;
  done
}

_m2_complete()
{
  local cur goals

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  goals='clean compile test install package deploy site'
  goals=$goals _m2_make_goals &quot;eclipse&quot; &quot;eclipse&quot;
  goals=$goals _m2_make_goals &quot;idea&quot; &quot;idea&quot;
  goals=$goals _m2_make_goals &quot;project-info-reports&quot; &quot;dependencies&quot;
  goals=$goals _m2_make_goals &quot;assembly&quot; &quot;assembly&quot;
  goals=$goals _m2_make_goals &quot;plexus&quot; &quot;app bundle-application bundle-runtime descriptor runtime service&quot;
  cur=`echo $cur | sed 's/\\\\//g'`
  COMPREPLY=($(compgen -W &quot;${goals}&quot; ${cur} | sed 's/\\\\//g') )
}
</pre>
<p>Quelle: <a href="http://www.caliban.org/bash/index.shtml">Working more productively with bash 2.x/3.x</a></p>
<p><a href="http://willcode4beer.com/tips.jsp?set=tabMaven">Wie das ganze für Windows und MAC eingerichtet wird, steht auf willcodeforbeer</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://olafsblog.sysbsb.de/maven-autocompletion-fur-die-shell-und-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
