Friday, 26 October 2012

Apache Maven site support Markdown !

Maybe you don't know because that's not very well documented :-) but Maven site support Markdown format ! It's just a matter of configuring the site plugin !
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-site-plugin</artifactId>
        <version>3.2</version>
        <dependencies>
          <dependency>
            <groupId>org.apache.maven.doxia</groupId>
            <artifactId>doxia-module-markdown</artifactId>
            <version>1.3</version>
          </dependency>
        </dependencies>
      </plugin>
Now add your markdown files with .md extension in src/site/markdown

And that's it ! You are now "à la mode" and you use markdown :-)

I agree that must be per default and no need of extra xml to write

See the documentation of under incubation Helix project, we use Markdown (http://helix.incubator.apache.org)

Have Fun

Wednesday, 10 October 2012

Test your local patch on a remote Jenkins with Maven

Recently Kohsuke (@kohsukekawa) wrote a plugin to let you apply a patch on Jenkins job for testing purpose.
See Blog entry.

That's a pretty good idea as most of the time, you can have very long build. Integrations tests with selenium running on various os/browsers (some you don't have or don't want to install) or tests on various databases.

So usually hack, commit/push the change and cross fingers for not break the build on your Jenkins instance (don't tell me you never did that :-) ).

While ago I started a Maven plugin to be able to interact with github/jira (see blog entry).

So I have enhanced this plugin a bit to generate a diff/patch (I have tested on both svn/git) and post it to Jenkins to run the job with applying the patch on the job workspace.

NOTE: you need to install the Jenkins plugin first Patch Parameter Plugin.

Then run the following Maven cli:
mvn patch-tracker:post -Dpatch.serverUrl=http://localhost:8080/job/maven-dependency-update-trigger-plugin -Dpatch.patchTrackerSystem=jenkins
Maven will ask you user/password etc..


Now that's cool you can keep your local cpu/memory to listen musics, watch videos, play games etc... while your patch is tested on a remote Jenkins instance.

NOTE: The maven plugin is still in sandbox without any release. So you need to install it manually (sources are here: https://svn.apache.org/repos/asf/maven/sandbox/trunk/plugins/maven-patch-tracker-plugin) or consume it from this snapshot repository: https://repository.apache.org/content/repositories/snapshots

BTW you can use curl too :-) curl --user uid:password -X POST -F "patch.diff=@patch.txt" https://jenkinshost/job/X/buildWithParameters?delay=0sec
Don't miss to add a build parameter patch file.
If you use svn, configure checkout-strategy to "Emulate clean checkout by first ...."

All feedbacks are welcome!

So Have Fun !

Friday, 14 September 2012

Publishing a Maven site to a scm (ease Apache svnpubsub usage)

The Apache Maven team just released a first version of a new plugin to be able to publish Maven websites to a scm. (Maven SCM Publish Plugin)
The first goal was to be able to commit web sites to the svnpubsub Apache infra for websites.

Remember the migration to svnpubsub is mandatory for the end of the year.

Yes you remember as (if you are an Apache committer) how long it can take to have a *.apache.org website live updated :-).

You usually scp to people.a.o and wait the end of rsync (long coffee break possible!) But now (thanks to Apache infra !), just commit your website to svn and the site is up2date within minutes !!

Note: as we have a Maven Scm Api we can support most of the supported scm by the Maven scm (honestly I have tested only svn and git :-)).
So it works too for git (github gh-pages included see documentation git branch section)

The trick is you must use different configuration and command line if you publish a mono module or multi modules build. See samples and documentation here:

Nice feature is the cleanup(delete) of not anymore generated files. They are now deleted from the scm. The plugin simply compare your generated website and the content from scm and take care of removing not anymore produced files.

Have a look at the other tips in this page.
The most important is to use the tryUpdate mode (not the default).
<tryUpdate>true</tryUpdate>
So have fun writing documentation on Apache projects and publish it to live very fast :P

Monday, 27 August 2012

Maven Assembly/Dependency plugins useJvmChmod field WTF ?

It looks not a lot folks knows a strange named option  from the Assembly and Dependency Maven plugins.
The name is useJvmChmod. Sure when reading this name you can say: "WTF ?????".
Both plugins use a component called plexus-archiver (which pack,unpack files and can set files permissions).
By default on unix platform, this component will fork a process to do chmod command line call and for each files (ouch !!!! for large distributions or unpack goal).
So long ago now (yup 2 years is long in our world :-)), I added a configurable mode to use file permission methods from jdk1.6 and not using anymore forked command line call to chmod.
This is why it's called useJvmChmod (sorry I'm sometimes not really good on naming marketing :-)).
By the way, if your build is still 1.5 that will works as it's done trough reflection (see initial commit ).
Note this option is available since assembly plugin 2.2 and it's now available in the fresh release of dependency plugin 2.5.1 (thanks to @atlassian folks for the issue report: https://jira.codehaus.org/browse/MDEP-368).
So if you assembly plugin or use unpack goal from the dependency don't miss this attribute to true!
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          or
          <artifactId>maven-dependency-plugin</artifactId>
          <configuration>
            <useJvmChmod>true</useJvmChmod>
          </configuration>
        </plugin>
NOTE: if you use useJvmChmod special permissions at group level won't be apply as it doesn't exists in java

Thursday, 2 August 2012

Maven Surefire configuration for CI server

I used this configuration for long time now but not sure you know that.
The use case is an application creating a temp file to store values (File.createTempFile( "wine.txt", "wine" ); )
Running it locally no problem.
But now you have a ci server running the same Maven project with various parameters:
* one fast only executing unit tests
* one longer running selenium integration tests.

On Unix server, the temp directory is shared for all users (usually /tmp, /var/tmp etc...).
So if your build runs in parallel they will share the same file (can go to weird results ..)

To avoid such case, you can configure surefire plugin as it


      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <systemPropertyVariables>
            <java.io.tmpdir>${project.build.directory}</java.io.tmpdir>
          </systemPropertyVariables>
        </configuration>
      </plugin>

As it each build will use a separate tmp directory and temporary files won't be shared anymore.


Wednesday, 9 May 2012

Java5 annotations support for Maven plugins

So finally or at least (depends on your POV :-)), I have pushed some code to support Java5 annotations support for Maven plugins.
The "specs" are here https://cwiki.apache.org/confluence/display/MAVEN/Java+5+Annotations+for+Plugins.
The code is available in the branch http://svn.apache.org/repos/asf/maven/plugin-tools/branches/MPLUGIN-189/.
Snapshot are deployed to: https://repository.apache.org/content/repositories/snapshot .
You can have a look at it tests to see some samples: http://svn.apache.org/repos/asf/maven/plugin-tools/branches/MPLUGIN-189/maven-plugin-plugin/src/it/annotation-with-inheritance/
Basically you need to setup your pom as it:
    <dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.0-SNAPSHOT</version>
      <scope>compile</scope>
    </dependency>


  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-plugin-plugin</artifactId>
        <version>3.0-SNAPSHOT</version>
        <configuration>
          <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
        </configuration>
        <executions>
          <execution>
            <id>mojo-descriptor</id>
            <phase>process-classes</phase>
            <goals>
              <goal>descriptor</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  
  <repositories>
    <repository>
      <id>apache.snapshots</id>
      <name>Apache Snapshot Repository</name>
      <url>http://repository.apache.org/snapshots</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>apache.snapshots</id>
      <name>Apache Snapshot Repository</name>
      <url>http://repository.apache.org/snapshots</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </pluginRepository>
  </pluginRepositories>

Annotations to use are:
@Mojo( name = "foo", 
       defaultPhase = LifecyclePhase.COMPILE, 
       threadSafe = true )
@Execute( goal = "compiler", 
          lifecycle = "my-lifecycle", 
          phase = LifecyclePhase.PACKAGE )

public class FooMojo extends AbstractMojo
{
    /**
     * the cool bar to go
     * @since 1.0
     */
    @Parameter( expression = "${thebar}", 
                required = true, 
                defaultValue = "coolbar" )
    protected String bar;

    /**
     * beer for non french folks
     * @deprecated wine is better
     */
    @Parameter( expression = "${thebeer}", 
                defaultValue = "coolbeer" )
    protected String beer;

    /**
     * Plexus compiler manager.
     */
    @Component
    protected CompilerManager compilerManager;

    /**
     *
     */
    @Component( role = "org.apache.maven.artifact.metadata.ArtifactMetadataSource", 
                roleHint = "maven" )
    protected ArtifactMetadataSource artifactMetadataSource;

    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        // nothing
    }
}
Note: the help generation doesn't work yet !!
A new feature is your parent annotated classes can come from reactor project and from your project dependencies.
And don't complain yet too much in case of issues, it's a work in progress :-)
12 May 2012 UPDATE: Help generation done and code merged in trunk YEAHH :-)
25 May 2012 UPDATE: Few annotations has changed have a look at documentation page: https://cwiki.apache.org/confluence/display/MAVEN/Java+5+Annotations+for+Plugins
31 May 2012 UPDATE: release 3.0 deployed and now available.
Have Fun!

Friday, 23 March 2012

Search and browse with Archiva new UI


If you follow me, you probably know I'm working on a new UI for Apache Archiva using plain html/javascript technologies (one page load app).
Here some screenshot about new Search and Browsing screens.

The new browsing



The new search


To test it just download:
  • zip with self contained jetty: http://s.apache.org/LAST_ARCHIVABUILD_ZIP
  • war to install in your favorite servlet container: http://s.apache.org/LAST_ARCHIVABUILD_WAR

So all comments are welcome :-)
And have Fun !

Wednesday, 15 February 2012

Apache Archiva UI rewrite progress (How it works ? )

Recently I proposed to rewrite the Apache Archiva UI. The goal was to have a new fresh/modern UI :-).
So as IANAD (D for designer) using Twitter Bootstrap was a good solution to help to start.
Regarding web framework buzz :-), I proposed to have a plain html/javascript (without any complicated Java web framework stack) maybe because it's "à la mode" :-).
At the end, it will be a one page load application with only javascript (data transfer with the server only tru REST call) and rendering with html/js template mechanism.
But here too there is some buzz around: which one to choose ? To have an easy UI automatic refresh, the data binding was something mandatory.
That's why http://knockoutjs.com/ was choosen !!
Furthermore it's a very active community, people are helping very quickly to help on mailing list and very documentation (something not usual on Open Source project :P ).
And definitely we didn't want waste time on philosophical discussions on various frameworks.
I promise I will write a blog entry soon on some tips to use this framework :-)

So the rewrite is in progress (see http://www.screencast.com/t/KX93fcKhHvE)
And some documentation on how it works has been started here
The top jira issue is here http://jira.codehaus.org/browse/MRM-1497.
Yes some job to do :-).
We are hiring :-) to complete all. So if you want to have fun with nice javascript framework. Do not hesitate to propose patches or pull requests tru https://github.com/apache/archiva.
Note: during the interview process, we won't ask complicated puzzle or scholar questions :-) you will be judged only on your patches proposal.

If you want to test the new UI, you can try the following steps :
svn co https://svn.apache.org/repos/asf/archiva/all/ archiva-all-sources
cd archiva-all-sources/archiva
mvn tomcat7:run -pl :archiva-webapp-js -Pjs -Pdev -am
Hit your browser : http://localhost:9091/archiva/index.html?request_lang=en

And after this UI rewrite, what's else ?
I'm thinking about plugins/extension points mechanism with UI part too. As the UI will be in full js, folks will have to write their plugins ui in js.
Maybe not only, Vaadin XS looks to be possible solution to study.
So stay tune for coming next news :-)

Saturday, 21 January 2012

Unit tests with embeded tomcat artifacts

In the 7.x releases of Apache Tomcat, some maven artifacts are now published which include a nice and fluent embeded api to run a Tomcat instance.

So it's a nice opportunity to use it writing units to test servlets, rest api etc..
But until 7.0.25 it was only possible to do it with using a barcoding port which can cause some issues on ci servers where you are not sure ports are not used by something else running.

I have personally sended a RFC to ITEF to have port allocation for only my personal use on my birthday year or zip code port but strangely this RFC was never approved :-).

Now you can use the java ServerSocket port 0 feature to use any free port available on the machine.
It has been fixed with the issue 52028.

So now you can write a unit test as it (here a test with a REST service provided by Apache CXF).



@Before
public void startTomcat()
throws Exception
{
tomcat = new Tomcat();
tomcat.setBaseDir( System.getProperty( "java.io.tmpdir" ) );
tomcat.setPort( 0 );

Context context = tomcat.addContext( "", System.getProperty( "java.io.tmpdir" ) );

A context param in your web.xml:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring-context.xml</param-value>
</context-param>

In the code

ApplicationParameter applicationParameter = new ApplicationParameter();
applicationParameter.setName( "contextConfigLocation" );
applicationParameter.setValue( "classpath*:META-INF/spring-context.xml" );
context.addApplicationParameter( applicationParameter );

A listener class in your web.xml:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

In the code

context.addApplicationListener( ContextLoaderListener.class.getName() );

CXF servlet declaration in your web.xml:

<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/restServices/*</url-pattern>
</servlet-mapping>

In the code:

tomcat.addServlet( context, "cxf", new CXFServlet() );
context.addServletMapping( "/restServices/*", "cxf" );

tomcat.start();

port = tomcat.getConnector().getLocalPort();

System.out.println("Tomcat started on port:"+port);
}



So now you can test/consume you REST services on localhost with the port.

Don't miss to shutdown the tomcat instance on tearDown or @After

@After
public void stopTomcat()
throws Exception
{
tomcat.stop();
}


If you use Maven you need the following dependencies:

<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<scope>test</scope>
<version>7.0.25</version>
</dependency>


As samples talks more than long docs ("Code talks, bullshit walks" :-) ).
The tomcat maven archetype has been improved with a sample. (see previous post)

Have Fun!

Friday, 13 January 2012

Tomcat Maven plugin archetype. Sample talks more than long documentation :-)

As code sample talks more than long and borying documentation (or maybe because I don't like to write too long documentation :-) ), I have writen an archetype for the Apache Tomcat Maven Plugin.

Some features describe in this post are now implemented.

As it's not yet released but soon !, just use :

mvn archetype:generate \
-DarchetypeGroupId=org.apache.tomcat.maven \
-DarchetypeArtifactId=tomcat-maven-archetype \
-DarchetypeVersion=2.0-SNAPSHOT \
-DarchetypeRepository=https://repository.apache.org/content/repositories/snapshots/
....
[INFO] Using property: groupId = org.apache.tomcat.maven
Define value for property 'artifactId': : tomcat-sample (project will be created in ./tomcat-sample )
...
cd tomcat-sample


You can run your webapp with: mvn tomcat6:run or mvn tomcat7:run (depends on tomcat version you want)
And hit your browser to http://localhost:9090 and you will use a very complicated hello world webapp sample :-)

Now you can try: mvn clean install .
You will see a selenium test running (by default firefox), use -Pchrome for using chrome should work too with -Piexplore (not tested :-) ).

Note you have now an executable war.
Try it !

cd basic-webapp-exec/target/
java -jar basic-webapp-exec-1.0-SNAPSHOT-war-exec.jar -httpPort 9191


And hit your browser to http://localhost:9191.
So you have a tomcat7 running our fabulous application and without installing nothing !

More details on the project



This archetype build a simple project with some maven modules. IMHO it's nice layout to use.

basic-api (service interface)
basic-api-impl (service default impl)
basic-webapp (our webapp module)
basic-webapp-exec (module to generated executable war)
basic-webapp-it (module to run selenium tests with generated war)


The application is exposing a REST service called HelloService (in basic-api module)


@Path( "HelloService" )
public interface HelloService
{
@Path( "sayHello/{who}" )
@GET
@Produces( { MediaType.TEXT_PLAIN } )
String sayHello( @PathParam( "who" ) String who );
}


The implementation is in the module basic-api-impl.
Note we use Apache Cxf to provide REST services (for more details have a look at the various spring files).

The webapp is a simple page based on jquery and twitter bootstrap.

So have fun !