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