How to cumulate property placeholder? - java

We have a classic Maven, Spring (3.1.1) application where we created an applicationContext.xml.
In this file, we have declared a property placeholder with an external file and a file in classpath.
Here an example found in another question here :
<context:property-placeholder location="file:${ADMIN_HOME}/db.properties,classpath:configuration.properties"
ignore-unresolvable="false" ignore-resource-not-found="false" />
It is working.
But now, we have a specific config file for JUnit tests.
In this config file, we have imported the first one and added a property placeholder for tests with a classic declaration.
<import resource="applicationContext.xml" />
<context:property-placeholder location="classpath:configuration-test.properties"
ignore-unresolvable="false" ignore-resource-not-found="false" />
We have injected a value from configuration-test.properties in JUnit test.
#Value("${junit.user.login}")
private String login;
But when we launch the JUnit, an error is raised.
The key "junit.user.login" is not resolved.
We don't know why.
Any idea ?
Thank you.

Is your junit launching the correct spring context?
You added the correct xml paths to the test case like so?
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/my-test-context.xml" })
public class TestCase{}

Related

Spring Web App Configuration doesn't take enviroment variables

I started setting tests for my project. It taked a while to settup the context. Now that I have achived it, I am getting trouble to make the tests work on multiple enviroments.
I set up the application test with these anotations:
#ContextConfiguration({"/applicationContext-test.xml", "/appServlet/servlet-context.xml"})
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#AutoConfigureMockMvc
public class ControllerUserTest {}
The trouble comes from the config file. When running the project on enviroments a parent config file values get replaced by environment ones. For testing for some reason I don't find a way to reproduce this. Meanwhile I setted up the parent config file with develop variables. To resolve this, the parent file was restored and using anotations like #TestPropertySource(properties="env=pre") or #ActiveProfiles("pre"). Neither way the parent file variables are replaced by environment ones. This kind of annotationa allows to change profile from class but It would be intereset to change the envoroment it from command line.
I also tried to use #BeforeClass annotation but the context annotations are executed before it.
To add more info about how the config is read. On "/appServlet/servlet-context.xml" I have a component-scan that points to a package where ApplicationConfig.java is stored . This config has this anotations #Configuration #PropertySource(value = { "classpath:nsf.properties" }).
In which direction I have to investigate to achieve my goal? Thanks in advance

gettign proxy of a bean in different project inside java class

I am new to the world of spring so i may ask a silly question but please let me the solution of my below problem please .
My problem is that I have two projects independent project nae is project A and project B ,now in project A i have the below xml configuration of bean
<bean id="abcService" class="com.jmx.JMXServiceImpl" autowire="no">
<constructor-arg index="0">
<ref bean="jobDetailsDomainHome" />
</constructor-arg>
</bean>
now in project A this bean get initilazied easily now i need this same bean initialized in project B also , so i have added project A in project B classpath also now please advise inside java class named rty of Project Bhow can i call this same bean abcService
The bean abcService depends on bean jobDetailsDomainHome. So there's no way to use abcService without the other bean.
You can split the configuration in various xml files. So define the abcService and the needed beans in one xml file, which is imported by the configurations of project A and project B.
<import resource="classpath*:service-context.xml" />
The import of xml files can use the classpath like shown above. But you can use locations in the file system too.
It's not important which bean is defined in which file as long as every needed bean is defined.

Configuring base package scan for Spring Boot Application at Runtime

I'm running a Spring Boot Application within a Tomcat instance packaged as a war file. I would like to be able to add "packages" to my instance in the form of rest services. To that end I need to be able to configure scanBasePackages in the #SpringBootApplication annotation at runtime. i.e. when tomcat starts up. For now I have ...
#SpringBootApplication(scanBasePackages="path1, path2")
public class RestApplication extends SpringBootServletInitializer {
//code
}
...but I would like to have path2 be configurable and alternately be able to add path3, etc. if desired. How can I achieve this? I understand that I can't configure the String in the annotation so my question is about what other alternatives I have to this annotation for setting this.
Cheers.
you can try to use something like this in your project
#Configuration
#Profile("custom-profile")
#ImportResource( {"file:path/additional-context.xml" } )
public class ConfigClass { }
and configure additional packages scanning in this file then.
<context:component-scan base-package="x.y.z.service, x.y.z.controller, x.y.z.dao" />
Note, your resource additional-context.xml declared as external and you have ability to change it without rebuilding war at all.
#ImportResource will be handled after declaring profile "custom-profile" as active. It's a safe way for starting application with "default configuration" without any "additional-context.xml" file of disk.
Have you tried this:
#SpringBootApplication(scanBasePackages={"path1", "path2"})
Hope this helps :)

BeanNotOfRequiredTypeException: spring factory not being resolved to child type

I'm having an issue with a PropertiesFactoryBean not being resulved to a Properties object in spring. Instead I get the following error:
org.springframework.beans.factory.BeanNotOfRequredTypeException: Bean named 'authProperties' must be of type [java.util.Properties], but was actually of type [org.springframework.beans.factory.config.PropertiesFactoryBean]
at org.springFramework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:367)
at org.springFrameowkr.beans.factory.support.AbstractBeanFactory.etBean(AbstractBeanFactory.java:198]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121
at *our code here*
This code was written by others who have used it reliably for some time, so the issue is likely configuration issue rather then bad code. However, the failure occurs on the return line of this method:
private static Properties getPropsFromContext(String context) {
try(AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(context)){
return ctx.getBeans("authProperties", Properties.class));
}
}
The relevant lines of the XML file are:
<bean id="authProperties" class="org.springFramework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:props/auth.properties" />
</bean>
Ultimately the code is being called from within tomcat. We are using our own RealmBase class for the tomcat Relm, which calls this code. The jar containing our RealmBase class is in the tomcat/lib directory.
What should happen is that spring should recognize that PropertiesFactoryBean implements the FactoryBean interface and it should call getObject of the PropertiesFactoryBean as part of the getObjectForBeanInstance called by doGetBean method, which would return the Properties object. However, for some reason this is not happening, and I'm getting the PropertiesFactoryBean object back instead of the Property being returned. I've even looked through the code to verify this.
Our unit tests of this method run fine, which once again suggests the failure is not with the code, but sometime after it gets compiled, likely a configuration issue with tomcat. As far as I can tell there are no duplicate spring jars in the tomcat classpath or other obvious naming collisions.
I'm using Tomcat6. Our spring jars are mostly 3.2.9, a few 3.1.0, but I think the relevant jars are all 3.2.9
Why would it fail to generate the Property value correctly?
I ultimately discovered I was running an outdated version of the realm jar. When I installed the new Realm things worked correctly. I assume my issue was that the old Realm was compiled to a different version of spring.

Importing Spring beans from other Maven modules inside a WAR?

I have a new web app that is packaged as a WAR as part of a multi-module Maven project. The applicationContext.xml for this WAR references beans that are imported from the "service" module, which in turn imports beans from the "dao" module. The import statement in applicationContext.xml looks like this:
<import resource="classpath*:service.xml" />
and the one inside the service.xml file looks like this:
<import resource="classpath*:dao.xml" />
Neither Spring STS, nor Eclipse show any warnings or errors in my bean files. I reference the imported beans all over the place. The Maven build works fine and the DAO integration tests all pass (they use the beans). I don't have any service integration tests yet.
But when I start up the WAR in Jetty I get an error:
Error creating bean with name 'securityService'
Cannot resolve reference to bean 'userDAO' while setting constructor argument
All of the imported bean XML files can be found inside their respective JAR files in the WEB-INF/lib directory. Indeed, the service bean that threw the error is itself defined inside the service.xml file inside the service module's JAR file.
Apparently the service module can't find the bean that it imported from the dao module. Obviously I don't understand something...seems like this should this Just Work?
I enabled DEBUG logging for 'org.springframework' in order to see if I could learn anything. What I found were messages to the effect that the DAO beans had been created, but there was also a message about them having no name or id.
I check the file, and they all did have an id. So what was it? I check the XML namespace and saw:
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
and noticed it was old (I am using Spring 3.0.2) and changed it to:
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
Once I changed it, Spring instantly threw half a dozen errors regarding beans that were defined incorrectly (but never used apparently). Once I fixed those errors, everything Just Worked. I've since gone through the entire system checking Spring XML file namespace versions.
Thanks to all for the help. Can't believe I wasted a day on this stupidity!!
The difference between the classpath:thingy.xml and classpath*:thingy.xml notation is that the former uses the standard classpath mechanism to resolve one resource (using ClassLoader.getResource(name)), whereas the latter will use ClassLoader.getResources(name) to retrieve all matching resources on the classpath, a distinction that should be irrelevant in your situation as I guess there is only one dao.xml file on the class path.
I think your problem is different, you are missing a leading slash.
Use this for a single resource
<import resource="classpath:/dao.xml" />
and this for multiple resources
<import resource="classpath*:/dao.xml" />
See
Spring Reference: The classpath*
prefix
Sun JavaDocs: ClassLoader
It should be like
<import resource="classpath:service.xml"/>
Are you having multiple applicationContexts and possibly the parent context is referring to a bean defined in the child context?

Categories

Resources