I’ve been working through the Spring Batch Getting Started page using the SpringSource Toool Suite (STS). Here’s a brief summary of some of the ‘fun’ I had ‘Getting Started’.
Creating the new project was easy enough but immediately I had a compile error as the org.springframework.jdbc.datasource.DataSourceTransactionManager
could not be referenced. The spring-jbc-3.0.6.RELEASE.jar
could not be opened in Eclipse and appeared to be corrupted. I removed it from the Maven repository and re-built the project. Maven downloaded a new version of the Jar and this appeared to be OK and the reference could now be resolved.
I also had this error: Error occured processing XML ‘Unable to load schema mappings from location [META-INF/spring.schemas]’. See Error Log for more details – on both the src/main/resource/META-INF/spring/module-context.xml
and src/main/resources/META-INF/launch-context.xml
files. I’m not sure if this is related to my corrupt Jar but all sorts of refreshing and rebuilding and restarting didn’t make them go away. In the end I just removed the errors from the Eclipse Problems View and as yet they haven’t come back.
I ran the tests both from Maven and from Eclipse and they ran fine – now to run the project as a standalone Java application. Here the docs dried up a bit but I found the exec-maven-plugin
section in the POM:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.1</version> <configuration> <mainClass>org.springframework.batch.core.launch.support.CommandLineJobRunner</mainClass> <arguments> <!-- job configuration file --> <argument>classpath:/launch-context.xml</argument> <!-- job name --> <argument>job1</argument> </arguments> </configuration> </plugin>
I could successfully run the project with mvn exec:java
and a I could run the project from Eclipse by creating a Run Configuration using this main class and arguments. Next to try from the command line.
I could see from the POM that a Manifest file was being created in our Jar with a main class and a class path, however when I tried to run the project with:
java -jar target\spring-batch-simple-2.0.0.CI-SNAPSHOT.jar classpath:/launch-context.xml job1
I got the error Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/batch/core/launch/support/CommandLineJobRunner
and I found that although the classpath was being created with a prefix of ‘lib’ none of the dependencies were being copied to a lib directory.
To rectify this I added the following to the POM.xml
<plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <phase>install</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin>
Which m2e didn’t like – reporting the error maven-dependency-plugin (goals "copy-dependencies", "unpack") is not supported by m2e
. Despite this maven install
did copy the dependencies.
Back to the command line and now I get Job Terminated in error: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]
.
I could see the spring.handlers
in the Jars but why weren’t they getting loaded?
Running this quick hack:
package rob; import java.io.IOException; import java.net.URL; import java.util.Enumeration; public class WhichResources { public static void main(String... args) throws IOException { ClassLoader classLoader = WhichResources.class.getClassLoader(); System.out.println(classLoader); Enumeration<URL> resources = classLoader.getResources("META-INF/spring.handlers"); while (resources.hasMoreElements()) { System.out.println(resources.nextElement()); } } }
Showed that only the handlers from the spring-jdbc-3.0.6.RELEASE.jar
could be found with the current class loader. Is this some feature of specifying the class path in the manifest? I couldn’t find any mention of this – but as explicitly specifying the class path is my preferred way of working I decided to move on to this. First I commented out the maven-jar-plugin
section of the POM and ran mvn:install
again.
Now with the classpath explicitly stated my WhichResources hack found all the handlers and with the command:
java -cp .\target\spring-batch-simple-2.0.0.CI-SNAPSHOT.jar;.\target\lib\aopalliance-1.0.jar;.\target\lib\aspectjrt-1.6.8.jar;.\target\lib\aspectjweaver-1.6.8.jar;.\target\lib\cglib-nodep-2.2.jar;.\target\lib\commons-dbcp-1.2.2.jar;.\target\lib\commons-io-1.4.jar;.\target\lib\commons-logging-1.1.1.jar;.\target\lib\commons-pool-1.3.jar;.\target\lib\hsqldb-1.8.0.7.jar;.\target\lib\jettison-1.1.jar;.\target\lib\junit-4.7.jar;.\target\lib\log4j-1.2.14.jar;.\target\lib\spring-aop-3.0.6.RELEASE.jar;.\target\lib\spring-asm-3.0.6.RELEASE.jar;.\target\lib\spring-batch-core-2.1.7.RELEASE.jar;.\target\lib\spring-batch-infrastructure-2.1.7.RELEASE.jar;.\target\lib\spring-beans-3.0.6.RELEASE.jar;.\target\lib\spring-context-3.0.6.RELEASE.jar;.\target\lib\spring-core-3.0.6.RELEASE.jar;.\target\lib\spring-expression-3.0.6.RELEASE.jar;.\target\lib\spring-jdbc-3.0.6.RELEASE.jar;.\target\lib\spring-test-3.0.6.RELEASE.jar;.\target\lib\spring-tx-3.0.6.RELEASE.jar;.\target\lib\xpp3_min-1.1.4c.jar;.\target\lib\xstream-1.3.jar org.springframework.batch.core.launch.support.CommandLineJobRunner classpath:/launch-context.xml job1
my spring batch project finally ran succesfully! Few.