0
votes

Is it possible to build a spring application jar file /w all jar dependencies packaged inside the jar as usual, but resources folder + spring app-context.xml defined outside the jar? If so can anyone point me to an example?

I want to build using maven, if possible, but maven squishes resources to the root of jar and i want those available/captured externally, so I guess there are actually 2 questions here.

  1. How do you make spring consume context/properties from external files. (ex. external "classpath*:/META-INF/spring/applicationContext.xml")
  2. How do you make maven package the jar file, NOT squishing resources to main jar. Though I guess this could be configured via a maven plug-in... I guess the first question is more important, I just figured there was some sort of a template solution for this, but have not been able to find an example.
3
I don't understand what you mean by externally. You mean outside of the jar? That's not possible if you want to run your application from one place. If you just don't want them at the root, put them inside folders that are inside your src/main/resources. Something like /META-INF/spring/applicationContext.xml is still on the classpath.Sotirios Delimanolis
outside the jar... what do you mean, "run your app from one place" you mean from a single jar? If so, that is correct. I want everything inside that jar but all xml and config stuff in an adjacent folder.niken
I don't understand what you mean by squishing then. Spring offers FileSystemXmlApplicationContextSotirios Delimanolis
Squishing = uber jar= jar with packages and classes inside it... No external dependencies to be read/loaded from filesystem... Adjecent in this context means on the filesystem "next to" the jar, so if i have folder/myawesome.jar i also have folder/config/* with all the spring resources and configs next to it. Is it amazing how many java programmers don't understand the basics of classloading? Some kids never take training wheels off their bikes :)niken

3 Answers

0
votes

How do you make spring consume context/properties from external files.

Use the Spring PropertyPlaceholderConfigurer:

<bean 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="locations">
        <list>
            <value>classpath:included.properties</value>
            <value>file:${HOME}/external.properties</value>
        </list>
    </property>
</bean>

The locations will be read in order, later items will override property values from earlier itmes.

How do you make maven package the jar file, NOT squishing resources to main jar.

If the first answer above helps you, there is no need for this.

0
votes

I think I know what you are getting at. You are trying to keep system-specific configurations outside of the package.

What I've done in the past is leave the applicationContext.xml inside the jar, but have a reference to an external one as well. That file contains the system-specific properties. I usually put it into the application container (tomcat)/lib directory.

If you are running a command line application, you can then just pass the file in as a -classpath arguement I guess.

I've just got a line like this at the top of my applicationContext.xml inside the artifact:

<import resource="classpath*:externalized-applicationContext.xml"/>
0
votes

I was eventually able to get this working using maven-shade-plugin to edit the manifest for uber jar. Once you get the xml incantations just right for the shade plugin, you have to set up rules for spring dependencies that have same-name handlers, which collide each other in classloader. Also you need to modify manifest classpath entries to include your folder names. If done correctly this will give you an "uber" jar + resources it uses sitting neatly in folders adjacent to it. Everything else is standard maven + spring stuff.