I am trying to acces a value defined in application.properties in a following way:
#Value("${server.url}")
private String serverUrl;
It works on embedded tomcat, but when I upload it to Weblogic I get the following error:
Error creating bean with name 'authorizationServiceImpl': Injection of
autowired dependencies failed; nested exception is
java.lang.IllegalArgumentException: Could not resolve placeholder
'server.url' in value "${server.url}"; nested exception is
java.lang.IllegalArgumentException: Could not resolve placeholder
'server.url' in value "${server.url}"
How can I make use of the application.properties file when hosting app on Weblogic server?
I found that if you want to use external properties on weblogic 10.3.6 you need to put the file in desired location and use the follwing annotation for setting property source in configuration/startup class:
#PropertySource(value = { "file:/...domains/MYdomain/application.properties" })
You should never place the application-XXX.properties files specific to an environment in the deployed component itself.
You should always externalize them outside it.
So, to solve your missing properties file problem, you have just to add the properties file(s) in a folder that you will add in the weblogic runtime classpath.
You can set the setDomainEnv.cmd/sh file of your domain and
add the folder path in the CLASSPATH variable.
For example, in Weblogic (11, 12 and maybe other older versions but not sure), in setDomainEnv.cmd, you should find this lines :
set JAVA_OPTIONS=%JAVA_OPTIONS%
#REM SET THE CLASSPATH
Replace #REM SET THE CLASSPATH by
SET CLASSPATH = %CLASSPATH%;yourPropertiesFilesAbsolutePath
Related
I am trying to externalize my ignite configuration in my spring boot application so the configuration can be changed without rebuilding the jar.
Previously the file resided in src/main/resrouces and was loaded via annotations.
#ImportResource("IgniteConfig.xml") and
#Autowired
private IgniteConfiguration cfg;
When I moved the IgniteConfig.xml to the config folder that resides next to the excutable jar the above stopped working and I have tried the following without success:
use --spring.config.location argument. I can tell this is picked up during run time as other configurations work but the above ImportResource annotation says the file IgniteConfig.xml cannot be found.
use a relative path to (e.g. ./config.IgniteConfig.xml) to Ignition.start. I cause this relative path to print the file contents of the xml file in my logs but when I pass it to Ignition.start it says the file cannot be found. I have tried using relative and absolute paths to do this.
Manually create an ApplicationContext and get the configuration by bean name.
ApplicationContext context = new ClassPathXmlApplicationContext("./config/IgniteConfig.xml");
This again complains that the file does not exist even though I can see by opening the file directly:
File igniteConfigFile = new File("./config/IgniteConfig.xml");
The comment by konqi in this post answered my question:
"In case you want to import a resource that is outside the classpath the syntax would be:
#ImportResource( { "file:path/spring-context1.xml", "file:path/spring-context2.xml" } )
"
In my case I just needed to do:
#ImportResource( { "file:./config/IgniteConfig.xml" } )
in my project there are 2 resource properties
1. application.properties
server.port=8002
spring.data.mongodb.host=
spring.data.mongodb.port=
spring.data.mongodb.database=
spring.data.mongodb.username=
spring.data.mongodb.password=
2. application-development.properties
server.port=8002
spring.data.mongodb.host=
spring.data.mongodb.port=
spring.data.mongodb.database=
spring.data.mongodb.username=
spring.data.mongodb.password=
spring.data.solr.host
this class uses the value properties of development
#Configuration
#EnableSolrRepositories(basePackages = {
"id.alfadigital.alfagift.service.product.v1.db.solr.repository",
"id.alfadigital.alfagift.service.product.v2.db.solr.repository"
})
public class SolrConfiguration {
#Value("${spring.data.solr.host}")
private String solrUrl;
#Bean
public SolrClient solrClient() {
return new HttpSolrClient.Builder(solrUrl).build();
}
#Bean
public SolrTemplate solrTemplate(SolrClient client) {
return new SolrTemplate(client);
}
}
I use application-development.properties as my project resoure
so I run the project with the following command :
mvn spring-boot:run -D spring.profiles.active=development
but an error is attached when I run the project
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'solrConfiguration':
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException:
Could not resolve placeholder 'spring.data.solr.host' in value "${spring.data.solr.host}"
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.data.solr.host' in value "${spring.data.solr.host}"
I'm confused, where are my mistakes, and how should I do?
Can you please run your application with following command. Because of wrong use of command it's not able to pick up the development profile.
mvn spring-boot:run -Dspring.profiles.active=development
Example:
how to use Spring Boot profiles
Provided you have the correct file name application-development.properties and correct Java Opts -Dspring.profiles.active=development, you must also place the profile specific properties file alongside with application.properties
Profile-specific properties are loaded from the same locations as standard application.properties
https://docs.spring.io/spring-boot/docs/2.1.12.RELEASE/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties
Make sure your properties file matches up with the name of your Spring profile as described here.
That is, if you are running from a "development" profile, Spring should pick up the application-development.properties file (or application-development.yml).
Then in your application.properties file you can specify your profile by using spring.profiles.active=development. Or you can specify the profile from the command line using -Dprofile as you mention.
As mentioned in in the link, "If several profiles are specified, a last-wins strategy applies. For example, profiles specified by the spring.profiles.active property are added after those configured through the SpringApplication API and therefore take precedence."
But also note that in your shared code you have no value for your spring.data.solr.host property.
I want load an external property file and set it values to another properties file, that is possible? e.g:
C:\properties\file.properties
id=userID
password=pass
./main/resources/application.properties
user.id=${id}
user.password=${password}
I tray run this command, but it isn't working
java -jar -Dspring.config.location=C:/properties/file.properties java-1.0-SNAPSHOT.jar
exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'id' in value "${id}"
You can use #PropertySource annotation from spring boot libraries.
Documentation and examples:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/PropertySource.html
I have a Spring Boot application that uses 3rd-party jar. This jar requires an xml config file, that must be provided by clients on runtime (individually) and cannot be pre-packaged. 3rd party lib loads that file using below sequence (I stripped ifs and null-checks):
FileConfigurator.class.getResource("/" + filename);
Thread.currentThread().getContextClassLoader().getResource("/" + filename);
Thread.currentThread().getContextClassLoader().getResource(filename);
I cannot change the way that lib loads the file (e.g. using Spring's Resource loading), so it must be on classpath. Therefore I seem to lose the possibility of executing it like java -jar my-spring-boot-app.jar, because -jar option prevents any additional classpath entries from being added. So I started running it like
java -classpath my-spring-boot-app.jar:./config/: org.springframework.boot.loader.JarLauncher
My directory structure is following:
|-- config
| |-- application.properties
| `-- 3rd-party-config.xml
|-- my-spring-boot-app.jar
But then Spring's autowiring started to fail: Additional application.properties file in config directory overrides some of settings and using above command causes app startup to fail:
Error creating bean with name 'ORBConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String com.company.app.communication.corba.orb.ORBConfig.serverName; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'application.corba.serverName' in string value "${application.corba.serverName}"
Field String serverName is annotated with #Value("${application.corba.serverName}"), the property is defined in application.properties file bundled within JAR and value injection works fine when additional application.properties is not present in config dir.
My actual question is: what is the advisable way of deploying and/or running Spring Boot application, to take advantage of executable Jar feature, provide additional classpath resources on runtime and still be able to override some (but not all) properties by classpath application.properties file?
Application is packaged using spring boot maven plugin and uses spring-boot-starter-parent parent POM.
One simple answer if you won't change the startup command:
move ./config/application.properties to ./config/config/application.properties
If there exist more than one classpath resources with same name, Spring Boot will load only one of them, in you case, Spring Boot load and prioritize property resources as following:
file:config/application.properties
classpath:application.properties which maybe resolved to either my-spring-boot-app.jar!/applcation.properties or ./config/application.properties
If your classLoader chosen ./config/application.properties as second property source. Bang!
Spring Boot's default configuration property resource path priority (highest to lowest precedence) is:
file:config/
file:
classpath:config/
classpath
The ordinary executable jar execution make those two configuration property fall into:
file:config/application.properties
classpath:application.properties (from jar)
And moving ./config/application.propertie to './config/config/application.properties' becomes:
classpath:config/application.properties
classpath:application.properties (from jar)
Both in the same order and have no ambiguous.
Grails have cofig for spring bean called resources.groovy. And as i understand from docs it allows you to include another file, using loadBeans(%path%)
I'm tried with this:
println 'loading application config ...'
// Place your Spring DSL code here
beans = {
loadBeans("classpath:security") //i'm tried with "spring/security" and "spring/security.groovy" also
}
but when grails is running it log following error:
Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Error evaluating bean definition script: class path resource [security] cannot be opened because it does not exist
Offending resource: class path resource [security]; nested exception is java.io.FileNotFoundException: class path resource [security] cannot be opened because it does not exist
at grails.spring.BeanBuilder.loadBeans(BeanBuilder.java:470)
at grails.spring.BeanBuilder.loadBeans(BeanBuilder.java:424)
at resources$_run_closure1.doCall(resources.groovy:13)
at resources$_run_closure1.doCall(resources.groovy)
... 45 more
Script security.groovy is exists at grails-app/conf/spring and compiled by grails maven plugin into target/classes/security.class.
Directory target/resources/spring is empty at this time
How i can configure Grails or grails-maven-plugin to copy this config files, not compile it into classes?
p.s. this problem also presents when i try to include config scripts using grails.config.locations = [ %path% ] inside conf/Config.groovy, my groovy scripts compiles into classes and because of it, grails config builder can't find them :(
Did you try:
println 'loading application config ...'
// Place your Spring DSL code here
beans = {
loadBeans("classpath:*security.groovy")
}
(this should load all Groovy files on the classpath ending with security.groovy and parse them into bean definitions).
Update: Found an interesting thread with this message as reference and my understanding is that one trick is to use ant in scripts/_Events.groovy to copy the .groovy file to the classesDirPath dir and then simply use:
beans = {
// load spring-beans for db-access via spring-jdbc-template
loadBeans('security.groovy')
// load some other spring-beans
...
}
This looks like a hack to get things working in both the war and when running run-app though. Not sure how things "should" be done (if this even makes sense).