Wednesday, August 21, 2013

groovy one liners on windows

Having seen perl one liners in the past, I was immediately drawn to groovy one liners.  Two posts from Dustin you would immediately get through google one & two.  So while playing with I ran into issue with quotes, rather escaping them.  Below one liner will wait forever:

groovy -e 'println "hostname".execute().text'

You should always use double quote to contain the one liner as below:

groovy -e "println 'hostname'.execute().text"
groovy -e "println java.nio.ByteOrder.nativeOrder()"

Thursday, February 14, 2013

ASO in Tapestry

I am into the third chap of this nice book Tapestry 5: Building Web Applications and ran into NPE while running the example that introduces Application State Object (ASO).  Even though I annotated it correctly (@ApplicationState) the object was not getting injected.

    @ApplicationState
    User user;

Action handler:
    Object onFormSubmit() {
        System.out.println("Handling form submission!");
        String[] words = getMessage().split(" ");
        if (words.length > 0) {
            user.setFirstName(words[0]);
            if (words.length > 1) {
                user.setLastName(words[1]);
            }
        }
        another.setPassedMessage(message);
        return another;
    }

Was getting NPE in my handler.  After trail and error what I realized is the access specifier for the variable must be private.  Only then the framework would inject.  Checked with @InjectPage as well.  Even if you provide setter method it is not working.

    @InjectPage
    private Another another;
    @ApplicationState
    private User user;

maven archetype catalog

I was playing around with tapestry and when I try to do a quick start as of today the number of archetypes that maven shows is about 726 and I didn't know what number to pick.  Then I realised that I can filter the list after the initial listing.

726: remote -> uk.ac.rdg.resc:edal-ncwms-based-webapp (-)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 251: org.apache.tapestry:quickstart
Choose archetype:
1: remote -> org.apache.tapestry:quickstart (-)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 1
Choose org.apache.tapestry:quickstart version:

I already know how to use the archetype:create if I know the archetype details as below:
mvn archetype:create -DarchetypeArtifactId=quickstart -DarchetypeGroupId=org.apache.tapestry -DarchetypeVersion=5.3.6 -DartifactId=quickstart -DgroupId=com.phani -Dversion=1.0 -DpackageName=com.phani.quickstart

We have few interesting options with archetype:generate -DarchetypeCatalog=??? as below (source):
archetypeCatalog:
The archetype catalogs to use to build a list and let the user choose from. It is a comma separated list of catalogs. Catalogs use following schemes:
  • 'file://...' with archetype-catalog.xml automatically appended when pointing to a directory
  • 'http://...' or 'https://...' with archetype-catalog.xml always appended
  • 'local' which is the shortcut for 'file://~/.m2/archetype-catalog.xml'
  • 'remote' which is the shortcut for Maven Central repository, ie 'http://repo1.maven.org/maven2'
  • 'internal' which is an internal catalog
For tapestry we can say
mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org

Tuesday, November 27, 2012

Assigning a string to shell variable with successive spaces

My friend Sumeeth called me saying that he is trying to assign a string with successive spaces to a shell variable, but the spaces are getting removed.

Linux environment, using bash shell

export test="Hello   World"

echo $test

Hello World <----------extra spaces in middle are removed.  This is because of IFS.  By default it will be set to <space><tab><newline>

So one way of doing this is to change IFS, do the assignment and put the IFS back.

export old_IFS=$IFS
export IFS="\n\t"
export test="Hello   World"
echo $test
Hello   World  <------spaces are retained

Thursday, November 8, 2012

Starting/Stopping hsqldb with maven

Starting hsqldb through maven with exec-maven-plugin is straight forward except for the confusion around arguments support.  Here is version with issue:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.2.1</version>
  <executions>
    <execution>
      <goals>
        <goal>java</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <mainClass>org.hsqldb.server.Server</mainClass>
    <arguments>
      <argument>--database.0 file:target/data/tutorial</argument>
    </arguments>
  </configuration>
</plugin>

Issue is with the highlighted line.  The value supplied with argument is passed as a whole single string.  What this means is in your java program argument count would be 1.  To start hsqldb we need to send the key and value for db location as seperate arguments.  We could use either args or nest argument as below:

<configuration>
  <mainClass>org.hsqldb.server.Server</mainClass>
  <args>--database.0 file:target/data/tutorial</args>
</configuration>

<configuration>
  <mainClass>org.hsqldb.server.Server</mainClass>
    <arguments>
      <argument>--database.0</argument>
      <argument>file:target/data/tutorial</argument>
    </arguments>

</configuration>

Now that we started the server, how to stop it?
<configuration>
  <mainClass>org.hsqldb.util.DatabaseManager</mainClass>
  <arguments>
    <argument>-driver</argument>
    <argument>org.hsqldb.jdbcDriver</argument>
    <argument>-url</argument>
    <argument>jdbc:hsqldb:file:test</argument>
    <argument>-user</argument>
    <argument>sa</argument>
  </arguments>
</configuration>

Connect using the UI  manager that comes along hsqldb and execute SHUTDOWN as query.

Friday, November 2, 2012

Ant related tasks in Maven

After using Maven dependency from within Ant, this time I had to find a way to call ant task from with Maven.  While trying to do a simple test around JMSMessageID behaviour (read about it on my java blog) with JBoss, I needed to include jbossall-client.jar on the classpath.  Here are couple of ways of doing this and their related issues.

Approach#1
Include jbossall-client as a dependency from JBoss public repository. Co-ordinates are org.jboss.jbossas:jboss-as-client, but this results in Maven downloading huge number of artifacts that are not requried. We would need to selectively include the required or exclude the unnecessary artifacts, which is not an easy job given the huge number.  See here and here for some help on this approach.

Approach#2
I tried adding a dependency with scope as system, providing the absolute path to the jbossall-client.jar.  Using system scope has its own issues, most critical being the dependency not being included on the classpath.  After going through lot of answers on stackoverflow zeroed on two approaches again - creating a local repository or using dependency and jar plugins.  But the problem is jbossall-client.jar

In JBoss 4.0, jbossall-client.jar used to include all the required jars/classes for a standalone client, which is changed since JBoss 5. Now the jar is sleek and refers all the jars through manifest. Issue with this is the jars won't be available if we jbossall-client.jar to some other location as the paths in the manifest are relative.

At this point I gave up and started running my Test directly from cmd by including the jbossall-client.jar in the classpath.  Then I came across two Maven plugins maven-ant-plugin and maven-antrun-plugin.  The former generates build scripts out of pom and the later can run any ant target from within pom.  The antrun plugin is what I tried as I felt the effort to setup maven local repository just to run my test program did not seem worth.  Here is what I came up with:



      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.7</version>
        <executions>
          <execution>
            <phase>test</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <target>
                <property name="runtime_classpath" refid="maven.runtime.classpath" />
                <java classname="com.sample.Tester">
                  <classpath>
                    <pathelement path="${runtime_classpath}" />
                  </classpath>
                    <pathelement location="JBOSS_HOME/client/jbossall-client.jar" />
                </java>
              </target>
            </configuration>
          </execution>
        </executions>
      </plugin>




Note that jbossall-client.jar is included later on the classpath otherwise it will try to bootstrap log4j (slf4j is part of jbossall-client.jar)


Please share if you done this differently.

Monday, October 29, 2012

Ant with maven dependency support - using maven-ant-tasks

Got hold of a nice book recently - Harnessing Hibernate from Oreilly.  While reading that, came to know about this ant task.  It would of immense help when you have an existing ant build and are in the process of migrating to Maven.  Using this task we can continue to use our build script and have all dependencies taken care by Maven.

Official page for Maven-Ant-Tasks

One can use the get task of Ant to dynamically download the jar and then include it in the build:

<get src="http://www.apache.org/dyn/closer.cgi/maven/binaries/maven-ant-tasks-2.1.3.jar"
  dest="${lib}"
  verbose="true"
  usetimestamp="true" />



A straight copy from above site:


<project ... xmlns:artifact="antlib:org.apache.maven.artifact.ant">
  ...
  <path id="maven-ant-tasks.classpath" path="lib/maven-ant-tasks-2.1.3.jar" />
  <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
           uri="antlib:org.apache.maven.artifact.ant"
           classpathref="maven-ant-tasks.classpath" />
  ...
</project>


Once setup, declaring dependencies is very easy.  Look at the usage page to know how to see how to configure repositories, reference your settings.xml from local maven install.  But note that to use this task you do not need maven to be installed at all!!  It downloads the artifacts to user.home/.m2 folder.