Maven appassembler plugin: change current directory before launching program

1k views Asked by At

Say I have a simple Spring application with a Main.java like so:

public class Main {
    public static void main(String[] args) {
        AbstractApplicationContext context = new 
            FileSystemXmlApplicationContext("config/application-context.xml");
        // do stuff...
    }
}

And I'm building the project with Maven and using the appassembler plugin thus:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>appassembler-maven-plugin</artifactId>
    <version>1.8</version>
    <configuration>
        <programs>
            <program>
                 <mainClass>com.jonarcher.Main</mainClass>
                 <id>foo</id>
            </program>
        </programs>
        <target>${project.build.directory}</target>
        <repositoryLayout>flat</repositoryLayout>
        <repositoryName>lib</repositoryName>
        <configurationDirectory>config</configurationDirectory>
        <configurationSourceDirectory>src/main/config</configurationSourceDirectory>
        <copyConfigurationDirectory>true</copyConfigurationDirectory>
    </configuration>
</plugin>

I have my project in $HOME/work/java/foo so I:

$ cd $HOME/work/java/foo
$ mvn clean package

... usual copious maven output ...

# make the script executable
$ chmod 755 target/appassembler/bin/foo 

# run it
$ target/appassembler/bin/foo


# aw...FileNotFoundException!
16:42:21,329  INFO .support.FileSystemXmlApplicationContext: 515 - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@11831d18: startup date [Wed Dec 17 16:42:21 MST 2014]; root of context hierarchy
16:42:21,369  INFO eans.factory.xml.XmlBeanDefinitionReader: 316 - Loading XML bean definitions from file [/Users/jarcher/work/java/foo/config/application-context.xml]
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from file [/Users/jarcher/work/java/foo/config/application-context.xml]; nested exception is java.io.FileNotFoundException: config/steve.xml (No such file or directory)

Looking at the foo script that appassembler has generated I notice it defines a $BASEDIR which is effectively the directory containing the assembled app (i.e. $HOME/work/java/foo/target/appassembler in my case).

Although $BASEDIR is passed to the program invocation it seems like a missed step for it not to cd $BASEDIR first...

exec "$JAVACMD" $JAVA_OPTS  \
  -classpath "$CLASSPATH" \
  -Dapp.name="steve" \
  -Dapp.pid="$$" \
  -Dapp.repo="$REPO" \
  -Dapp.home="$BASEDIR" \
  -Dbasedir="$BASEDIR" \
  com.jonarcher.Main \
  "$@"

OK so I could:

$ cd $HOME/work/java/foo/target/appassembler # or wherever my app ultimately is installed
$ bin/foo

And all's well, but I don't really want the constraint of people having to be in the correct directory just to start it(!)

So am I missing something? Is there a way to change this easily? Am I thinking about it wrong?

(I realize I could use the app.home property that gets passed in but that's just a cascading chain of hassle...)

1

There are 1 answers

1
Jon Archer On

OK in case this is useful to anyone else in the future I was able to alter the template used to generate the script to change directory as I wanted.

The original template can be snagged from here. Place into your project and edit as necessary.

And then just add the following into the appassembler configuration section:

<configuration>
    ...
    <unixScriptTemplate>${project.basedir}/path/to/script/template</unixScriptTemplate>
</configuration>