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).
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" } )
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.
In a Spring-boot application, I was having a single module and I was able to inject a configuration file, e.g. "my.properties", that was located in src/main/resources as follows:
#Configuration
#PropertySource("/my.properties")
public class MyConf{
}
Everything was ok, but then I created submodules and now I moved that configuration file in a submodule. When I start the main application I gedt the following exception:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.myapp.MainApplication]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/home/jeanvaljean/workspace/mainmodule/secondarymodule/my.properties]
As I see, I can solve the issue by writing
#PropertySource("/src/main/resources/my.properties")
Doing this, the path is correct and the file can be loaded.
Anyway, that is an horrible solution, and I'm pretty sure that there is a more elegant and flexible alternative. Any solution?
Spring has a few different implementations of how to find a resource. By using the prefix classpath: you are telling Spring to search for the resource in all the classpath, rather than in the classes that are bundled with your application.
Depending on the ApplicationContenxt, Spring will use a different default Resource class. It looks like in your case, Spring was instantiating a FileSystemResource, which only finds files available on the filesystem with either relative or absolute paths (but not inside jars!). My rule of thumb is to never prefix something if it's in the same module/component/jar, and always prefix it with classpath: if I know it's in a different module/component/jar (some people get mad at this :).
You can read a more in the Spring Documentation - Resources
I'm working on a java project with spring on eclipse using Maven, and running on a Tomcat server v6.0. Everything was working fine since yesterday morning.
Here his my problem : I'm building my project, I got a build success. Then I start my Tomcat server and got this error :
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:applicationContext- core.xml]
Offending resource: ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext-core.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext-core.xml] cannot be opened because it does not exist
I found out similar problem on some website but none of them give me a solution that worked for me.
It seems that eclipse isn't able to find applicationContext-core.xml when I'm doing this :
<import resource="classpath:applicationContext-core.xml" />
However, I do have the needed jar file nad-core-0.0.1-SNAPSHOT.jar in WEB-INF/lib containing applicationContext-core.xml.
I even tried to add it manually to the classpath but I was still having the same problem.
I keep on looking for a solution, when suddendly it work again once after restarting Eclipse and building while Eclipse was still updating indexes and my project was having this strange status Hg status pending instead of default. Surprised by this result I decide to build again my project after restarting Eclipse and I got the error again and I enable to make it work again. It's quite annoying...
This looks to be a really random problem.
Thanks a lot for your help :)
As you've not specified you web application structure. I assume you've a simple web application at hand with the following structures
webapp
WEB-INF/classes/applicationContext.xml
WEB-INF/lib/nad-core-0.0.1-SNAPSHOT.jar/applicationContext-core.xml
Application context.xml refers to the applicationContext-core.xml file using the import tag. I did encounter a similar situation in my web application, here're the check lists that you should go through and may be one of them can apply to your situation.
Check the generated snapshot jar file for the applicationContext-core.xml file and make sure it is in the root directory of the jar. As silly as it sounds, this was the root cause of the issue I faced in my deployment.
Make sure your Maven Pom.xml file is configured to include this XML file from the resources folder. You can use the resource tags in the build phase of Maven to package them within the jar file itself.
You can try removing the import tag from application context.xml file and instead load both of them from Spring's webapplication context itself.
Add a context loader listener class from spring org.springframework.web.context.ContextLoaderListener
Add context-param contextConfigLocation with value classpath:applicationContext-core.xml,classpath:applicationContext.xml. Spring has the ability to dynamically sort out the dependencies before initiating the bean factory.
Hope this check list helps.
I get pretty much the same config, six years later, I got the same error.
I also restart Eclipse, and it solved the issue.
I am using IntelliJ and jus checked out working code from the svn.I am struggling to run the jar.
Its a simple core java Spring project.
Since I get the above error.I understand that the spring path is not set fine.
How do I handle it.?
private ApplicationContext appContext = new AnnotationConfigApplicationContext(ApplicationRepositoryConfiguration.class);
Application context file is a bean class here (#Bean annotation is used). I am not using a xml file.
It seems like you are running your project from command line. Run following command :
java -classpath spring.jar;spring-sec.jar,......so on com.example.UrMainClass
while specifying jar in command, make sure you provide complete path of jar. Also check this link https://stackoverflow.com/a/10122038/1065180