Fun Getting Started with Spring Batch

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.

Comments are closed.