Creating double-clickable 'uber' jar that pulls in other jars of a spring application
I have a mavenized, multi-module spring-based(3.0.1) application that runs in tomcat. I'm trying to create a standalone tool that I can distribute to users via a single jar(so they can just double-click on it), that bundles in some of the modules of the application mentioned above.
I've used the maven-shade-plugin to assemble this jar. If I explode the jar it appears as if all of the dependencies are there and the two spring metadata files have been properly concatenated from all of the individual spring jars. The application runs, up until the point where I attempt to instantiate a ClassPathXmlApplicationContext
. When a user clicks a button in the application, the following method is executed:
public void createAppContext() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext(springFiles);
}
"springFiles" is declared in the class as follows:
public final String[] springFiles = { "/applicationContext-beans.xml" };
When the above method is executed the following error appears:
Exception in thread "Thread-8" java.lang.ArrayIndexOutOfBoundsException: 3350 at org.springframework.asm.ClassReader.(Unkno开发者_JAVA技巧wn Source) at org.springframework.asm.ClassReader.(Unknown Source) at org.springframework.asm.ClassReader.(Unknown Source) at org.springframework.core.type.classreading.SimpleMetadataReader.(SimpleMetadataReader.java:48) at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:80) at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:82) at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:76) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.checkConfigurationClassCandidate(ConfigurationClassBeanDefinitionReader.java:302) at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:157) at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:132) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:584) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:405) at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:93) at com.mycompany.StandaloneTool$2.run(StandaloneTool.java:124)
Any help would be greatly appreciated!
Just a hunch but it may be the shade plugin overwriting the metadata that Spring uses for it's namespaces in the configuration file. Have a look at merging content of specific files in the documentation for the shade plugin to see if it solves your problem.
The spring meta-data files appeared to be copied correctly. I started using the maven-shade-plugin for this specific reason. :)
I upped the spring logging to TRACE, which revealed some more information(I should have done this to start, oops!). I was getting a bunch of exceptions saying that various .class files had invalid java magic numbers.
It turns out that the issue was in how I was using the maven-dependency-plugin. My intent was to pull in a .zip artifact, unpack it, and copy it's contents to a specific build directory during the generated-resources phase. One potential problem is that I had inadvertently used the goal "unpack-dependencies" which pulled in more dependencies than I had intended(dependencies that ultimately the maven-shade-plugin would bundle in anyway). However, what seemed to finally resolve the issue was the removal of the artifact item property "output-directory" where I specified a directory called "generated-resources". Once I removed this property, everything ran smoothly.
It's not clear to me why the magic numbers on the .class files were being changed/corrupted, but at least the problem has been resolved. Anyone have any ideas as to what actually happened?
Thanks for all the input!
精彩评论