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.