I have a tomcat application with jndi.xml file that has placeholder. This file contains placeholder ${...} and I want it to be replaced from environment variable.
jndi.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"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
<bean id="widgetsRestBaseUrl" class="java.lang.String" factory-method="valueOf">
<constructor-arg value="${widgetsRestBaseUrl}"/>
</bean>
</beans>
pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.13.RELEASE</version>
</dependency>
From my understanding, PropertySourcesPlaceholderConfigurer resolves ${...} in bean definition , so I expected it to work, but it doesn't. Am I missing anything from here? I do see PropertySourcesPlaceholderConfigurer class in my project from spring. And I also do set environment variable, checked using printenv.
EDIT: I found that I need to have some <context:property-placeholder />, but not sure what it means.
Exposing jndi variables as property place holder
After some research, I found that adding <context:property-placeholder ignore-unresolvable="true"/> in my context.xml file did the trick. From Exposing jndi variables as property place holder
Related
I have a problem with Environment env.getproperty, env not find local properties, but it find system properties. I dont know about this so much and I need to solve it. Please, help me.
Attached my code and its configuration.
Controllers.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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- Scans within the base package of the application for #Components to
configure as beans -->
<mvc:annotation-driven />
<context:component-scan base-package="com.mret.client.controller" />
<context:component-scan base-package="com.mret.client.security" />
<context:property-placeholder location="classpath*:paremeters.properties" />
Paremeters.properties:
url.services.search=http://localhost:8080/mretcore/search
url.services.orderdetail=http://localhost:8080/mretcore/orderdetail?orderid=
Controller:
#Controller
public class OrdersController {
RestClient restClient = new RestClientImpl();
#Autowired
private Environment env;
String url = env.getProperty("url.services.search");
etc....}
enter image description here
property-placeholder does not place properties into env. It is for variables set on OS level.
better use System.getProperty("property_name") which includes env, JVM properties, -D properties passed into java command line and yes - those from property-placeholder.
Also you may consider to use your url as bean property and do not get it explicitly, but by spring bean property definition like ${url.services.search}
instead of having property name in code. After time it may hard to find where what property loaded. It is better approach...
I've read Spring In Action, and prefer Java config over XML config. So I used Java config to write my app, but our deployment environment requires me to use XML config. So I wrote an XML config, and it's only function is to import the root Java config.
The Java config code looks like this:
package com.somegroup.app;
#Configuration
#ComponentScan(basePackages = "com.tianchengsys.crawlers.cqs")
public class AppCtxConfig {
#Bean
public SomeType aSomeType() {
return new SomeType()
}
}
and the XML config looks like this:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<context:annotation-config />
<bean class="com.somegroup.app.AppCtxConfig" lazy-init="false" />
</beans>
When I created a ClasspathXmlContext("classpath:spring-context.xml") in Eclipse, the SomeType bean defined in Java config is initialized, and registered to springs ApplicationContext. But when I deployed this app (all dependencies are in a lib directory), the AppCtxConfig bean defined in the XML config was just treated an ordinary bean (not configuration).
It was created, but the beans defined in it were not initialized. Spring some times warned the someType method in the Java config should be static. I did changed it to static, it also didn't work.
This is because you are creating AppCtxConfig as a regular bean, which it isn't.
As the commentor suggested, add the component-scan on and set base-package to the package where your config class is located in:
<!-- Scan the JavaConfig -->
<context:component-scan base-package="com.somegroup.app" />
If your app package is the root package, with all subpackages inside, add a new config package and move the AppCtxConfig inside it.
So add:
<!-- Scan the config package with AppCtxConfig inside it -->
<context:component-scan base-package="com.somegroup.app.config" />
I'm trying to have my project's Strings/ messages stored in an external .properties file. I think I have everything wired up OK, but still I get:
org.springframework.context.NoSuchMessageException: No message found under code 'subtype.user.client' for locale 'null'.
Whenever I try:
String string = messageSource.getMessage("subtype.user.client", null, null);
My spring xml config files are as follows. Since the project is really big with lots of beans, I have different spring xml config files defining different types of beans, and a main spring.config.xml file that wires them all together.
Messages file named messages.subtypes
subtype.user.user=User
subtype.user.client=Client props
subtype.user.staff=Staff
subtype.user.clerk=Clerk
subtype.user.secretary=Secretary
Messages beans file called spring.messages.config.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<list>
<value>messages.subtypes</value>
</list>
</property>
</bean>
<bean id="myProjectLangs" class="myprojectbase.MyProjectLangs">
<property name="messageSource" ref="messageSource"></property>
</bean>
</beans>
The main spring.config.xml config file that wires all the beans together via <import resource="classpath:filename.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:aspectj-autoproxy />
<import resource="classpath:spring.messages.config.xml"/>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" />
<context:annotation-config />
<context:component-scan base-package="myprojectbase"/>
</beans>
You get this error because you pass the Locale parameter as null. Try
String string = messageSource.getMessage("subtype.user.client", null, Locale.ENGLISH);
Even though you have not defined a file messages.subtypes_en.properties defined it should fall back to messages.subtypes.properties
A couple of things come to mind looking at your code any of which might cause the problem:
Your xml config name contains "." as separators. This is against conventions. Consider renaming your config file to spring-messages-config.xml
Your language properties file has no properties suffix, again convention suggests to name this file messages-subtypes.properties
In both your application context xml files you define a bean named messageSource. Consider deleting one of them.
My prime suspicion as to why your code does not work lies with the way you define basename on ReloadableResourceBundleMessageSource. Looking at the JavaDoc for setBasename method there is some form of convention of configuration at work:
Set a single basename, following the basic ResourceBundle convention of not specifying file extension or language codes, but in contrast to {#link ResourceBundleMessageSource} referring to a Spring resource location: e.g. "WEB-INF/messages" for "WEB-INF/messages.properties", "WEB-INF/messages_en.properties", etc. XML properties files are also supported: .g. "WEB-INF/messages" will find and load "WEB-INF/messages.xml", "WEB-INF/messages_en.xml", etc as well.
This suggests that once you have renamed your message properties file to messages-subtypes.properties, you should change your config to <value>classpath:messages-subtypes</value>, make sure that the file is in the classpath and everything should start working.
Try renaming the messages.subtypes file to messages.subtypes.properties.
It is useful to have different property sets for different users.
<?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:property-placeholder
location="classpath:/path/to/package/default.properties,
classpath:/path/to/package/#{ systemProperties['user.name'] }.properties"/>
</beans>
When executing the application, spring does not recognize the expression. The context does not start and spring says: class path resource [path/to/package/#{ systemProperties['user.name'] }.properties] cannot be opened
When I replace the expression manually with a string resulting in a valid resource then the behaviour is as expected. The manual states it should work.
The spring-context and spring-core (3.1.2-RELEASE) are in classpath.
How come spring does not pick up the environment variable?
I'm open to alternate solutions solving the same functional problem.
SpEL expressions are not allowed there; you can do what you want indirectly, though...
<context:property-placeholder properties-ref="props"/>
<util:properties id="props" location="classpath:#{systemProperties['foo']}"/>
Here is the complete answer to the question. Keeping the override of user properties over default properties. My edit of the accepted answer got rejected.
<context:property-placeholder properties-ref="springContextCongifurationProperties"
location="classpath:/path/to/package/default.properties"
local-override="true"/>
<util:properties id="springContextCongifurationProperties"
location="classpath:/path/to/package/#{ systemProperties['user.name'] }.properties"/>
Is there a special way for doing this?
What i got is:
config.properties with param.key=value
web.xml with ContextLoaderListener that reads the configuration
pages-servlet.xml that defines servlet beans.
What I want is to configure one of the beans in pages-servlet.xml with param.key.
I'm using <property name="myField" value="${param.key}"/> in the xml but I see that the field is configured with ${param.key} instead of 'value'.
What is the right way to configure the bean?
Ok, I solved it by importing application context file that defines configuration bean into pages-servlet.xml.
It works, but seems very wrong.
Property placeholder is what you want.
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:property-placeholder location="classpath:/config.properties" />
<bean id="mybean" class="...">
<property name="xxx" value="${prop.value}" />
</bean>
</beans>