How to import Spring application context from another maven module? - java

I have two modules in my project which are children of the main app.pom
<modules>
<module>commons</module>
<module>webapp</module>
</modules>
The webapp module refers to commons this way:
<dependency>
<groupId>com.app.whatever</groupId>
<artifactId>commons</artifactId>
<version>${project.version}</version>
</dependency>
The commons module is just packaged in .jar file and that's it. All their dependencies webapp and commons inherit from app.pom.
Both commons and webapp use Spring 3 with .xml files that describe application contexts.
In webapp module I want to use a bean from commons module. Here's applicationContext for commons:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.app.whatever.anything"/>
</beans>
For webapp applicationContext.xml I have:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<import resource="classpath*:/applicationContext-commons.xml"/>
<context:component-scan base-package="com.app.whatever.something.controller.spring"/>
But unfortunately this doesn't work. Constantly get an exception about no candidates for autowiring, though I can use any classes from the second module in the first one after setting the above maven dependency.
When I write this import without asterisk, it says that the file doesn't exist.
I tried without leading slash - the same exception.
This import works perfectly for any file from the same module and even for external libraries I have. But it can't resolve the file from this new commons module I've just created.
If you have any idea, that'd be really helpful, thanks

If it's not under a subdirectory, e.g. spring/applicationContext-commons.xml then the following (which you've already tried) should work:
<import resource="classpath*:applicationContext-commons.xml"/>
With an asterisk, Spring will use all matching files on the classpath, without the asterisk it will use the first one it finds.
Also, with the asterisk Spring will ignore the file if it wasn't found. Without the asterisk Spring will give an error if it can't find the file. Therefore your file is not on the classpath.
I'd check the location of applicationContext-commons.xml under the target folder to make sure <import resource= has the correct path and re-run mvn install from the root pom.

Related

Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace

I am facing a lot of issues one after the other. Let me note it down properly -
I am implementing Springframework cache and this was my original SpringCacheConfig.xml -
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:hz="http://www.hazelcast.com/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.hazelcast.com/schema/spring http://www.hazelcast.com/schema/spring/hazelcast-spring.xsd">
This was working fine in my laptop, but in the test VM, we were not able to download the XSD schema files from internet.
So I changed the schemalocations to classpath -
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:hz="http://www.hazelcast.com/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:spring-beans.xsd
http://www.springframework.org/schema/cache classpath:spring-cache.xsd
http://www.springframework.org/schema/context classpath:spring-context.xsd
http://www.hazelcast.com/schema/spring classpath:hazelcast-spring.xsd">
So now the XSD files were picked up. But the downloaded spring-context.xsd file has the following content -
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="https://www.springframework.org/schema/beans/spring-beans-4.3.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="https://www.springframework.org/schema/tool/spring-tool-4.3.xsd"/>
So I have again moved them to classpath.
After these changes if I now execute our code, I am getting the following error -
Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]
Offending resource: class path resource [SpringCacheConfig.xml]
I tried to solve this problem by many previous posts, but not able to.
The pom is already including spring-context related jars -
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework.version}</version>
</dependency>
These jars are not packaged within the main jar, but are available at
modules/system/layers/thirdparty/org/springframework/main/spring-context-4.3.1.RELEASE.jar.
But why the jar couldn't be found?
I also tried the shade plugin, but still dependency jars are not included -
How to create spring-based executable jar with maven?
What else should I think about?
I don't have the META-INF/spring.handlers etc Spring related files within the jar. Can it be the issue?
I solved the problem by creating a META-INF directory and putting the spring.handlers and spring.schemas files into it. I extracted all the spring jars, some of them have these spring.handlers and spring.schemas files. I concatenated the contents of those files and put them in META-INF.
But surprisingly, the project was working in eclipse, but not in VM. In eclipse project, I don't need to copy the spring.handlers and spring.schemas files in the jar's META-INF directory - it works without them. But in VM I need to copy the files! May be in eclipse these files are referred from .m2, since those jars are in the classpath? Any idea?
Thanks

Spring mvc cannot find CacheInterceptor

I'm exploring cache in spring mvc framework. Following the guide on internet like here or here, i'm configuring:
<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven />
... other configuration are omitted....
</beans>
Before adding configuration for cache, my web app run normally, now, my web app start with error:
java.lang.NoClassDefFoundError: org/springframework/cache/interceptor/CacheInterceptor
Not sure what i did wrong?
A NoClassDefFoundError is simply an exception that is thrown when java can't find a certain class that another library uses.
All this means is that when it gets thrown you just need to get it on the classpath. You can make sure it's there by going to libraries-> maven dependencies(if you are using maven) -> and then go to the location of the noclassdef that is being thrown, in your case it would be at org/springframework/cache/interceptor/CacheInterceptor, this is just so you know why you are getting this error, you should not see it now.
As for how to solve it, this could be happening because of 3 things:
Your maven dependencies are not on the deployment assemblies(libraries are in the project, but not on the server), although probably spring wouldn't work at all if this was the case.
You don't have the dependency, add this to pom.xml:
org.springframework
spring-context
4.1.4.RELEASE
You have conflicting spring versions, make all version tags the same.

Maven Project: Spring cannot find property file inside src/main/resources using PropertyPlaceholderConfigurer

Spring cant find my property file (MyPropFile.properties) inside src/main/resources and throws an exception like below
java.io.FileNotFoundException: class path resource [file*:/src/main/resources/MyPropFile.properties] cannot be opened because it does not exist
But if I place MyPropFile.properties at the root of my project (MyProject/MyPropFile.properties) spring can find it and the programs executes properly.
How do I configure this so that I can place my .properties file inside src/main/resources
this is my namespace
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
this is my bean
<context:property-placeholder location="classpath:MyPropFile.properties" />
Java:
#Value("${message.fromfile}")
private String message;
Thanks in advance guys.
Try this. Make this entry in your application config file:
<beans xmlns:context="http://www.springframework.org/schema/context"
.....
xsi:schemaLocation="...
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
....>
<context:property-placeholder location="classpath:MyPropFile.properties" />
....
</beans>
and access the message property:
#Value("${messageFromfile}")
private String message;
I'd expect Maven to copy this to the target directory and for the classpath to be set appropriately. I wouldn't expect Maven to search the source directory other than at compile time.
You should use
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:/MyPropFile.properties</value>
</property>
</bean>
Without the classpath: prefix, the PropertyPlaceholderConfigurer is attempting to resolve the resource as a file resource, so is looking for it in your current working directory.
As an addendum to #ryanp solution which is the correct and sanitized way to deal with files resources, which should be under the classpath location.
Maven will automagically collect the configured file resources and append them to your runtime classpath holder so that resources prefixed with classpath: can be resolved.
Otherwise, if you find your self stack with Maven not being able to stream file resources, you may hook into Maven's resources configuration and map your files location as follows:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include>
</includes>
</resource>
</resources>
</build>

Failed to read schema document Schema Cloudfoundry

I'm developing an app with Java and Spring and I'm trying to upload it to AppFog.
The application is working properly and it's working in AppFog, but in Eclipse I'm getting a very annoying error in my applicationContext.xml file.
According to the documentation in AppFog I have to set it up like this: Spring - AppFog Documentation
Snippet of my applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cloud="http://schema.cloudfoundry.org/spring"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://schema.cloudfoundry.org/spring
http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd">
<cloud:data-source id="dataSource">
In the tag cloud:data source I'm getting the error:
Multiple annotations found at this line:
- schema_reference.4: Failed to read schema document 'http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd',
because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
- cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'cloud:data-source'.
I've tried with http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd and different versions but I'm always getting the same error.
I have included in my pom the next library too:
<dependency>
<groupId>org.cloudfoundry</groupId>
<artifactId>cloudfoundry-runtime</artifactId>
<version>0.8.1</version>
</dependency>
Some ideas?
Thanks!
So it looks like your app is working locally and on AppFog, but as you say the issue is a validation error in Eclipse. Are you using the Spring Tool Suite plugin? What should actually happen here is that the schema should be found within the Spring Jar file (the source is on Github https://github.com/cloudfoundry/vcap-java/blob/master/cloudfoundry-runtime/src/main/resources/META-INF/spring.schemas) - I guess there should be a way of telling Eclipse to resolve it there, and I suspect that STS would actually know how to resolve it.

Spring Configuration Error: (cvc-etl.1)

I tried everything I can think of, but nothing seems to work.
I am using the current version of Spring Framework (3.2) in my java web application.
Every time I start my project I get the following error:
cvc-elt.1: Cannot find the declaration of element 'beans'
this is my applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
</beans>
I tried to :
change the version of the schema (3.2, 2.0...)
copy the schema from the jar into WEB-INF
change unix EOL into windows EOL
and nothing seems to work, except using the DTD declaretion instead of the XSD.
What should I do?
Spring is having trouble finding the xsds. Take a look at this SO post. If you are sure you have the required spring-beans jar in your classpath, you may have a corrupted META-INF/spring.schemas file. The spring.schemas file tells spring which classpath to use to find the corresponding xsd file in the spring jars. I have had this occur when using the maven-shade plugin improperly configured.
The xsd came down fine for me when I pasted it in the browser.
This one works fine for me:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="example"/>
</beans>

Categories