Spring - Combing Java Config and Xml to reference a bean defined in legacy XML - spring

Is it possible to configure a classpath resource for a Java bean in any other location in the classpath than src/main/resources? I have an application which picks up its configuration files from src/main/app/conf/beans.xml. I want to use the bean defined in the xml configuration in my JavaConfig configuration, how can I specify the location in a JavaConfig file, for example something like below?
#Configuration
#ImportResource("classpath:..beans.xml)
public class AppConfig{
// Reference Bean
#Autowired
private MessageLoader loader;
}

That is certainly possible. If your resources are not present in src/main/resources then, you can specify that directory in your POM.
<resource>
<directory>[your folder here]</directory>
</resource>
Reference here

Related

How to get data for a particular log4j2 property from an alternative source (application.properties)

Having a standard configuration for log4j2 and spring property-file on classpath application.property.
log4j2.xml
<Properties>
...
<Property name="APP_LOG_ROOT">${bundle:application:log.root.dir}</Property>
...
</Properties>
application.properties
...
log.root.dir=/opt/tomcat/logs
...
The data is read into the log4j2.xml correctly, but what if I want to get an alternative property when creating an artifact with maven and put diferent application.property:
mvn clean install -Dapplication.properties.path=file:/some_path/application.properties
?
After that, I can correctly read the new properties.
#Value("${log.root.dir}")
private String ololo;
but the log4j2 cannot do this on its own.
If you want to use any value from Spring's Environment in a Log4j2 configuration file, you need to use the Spring Boot Lookup.
After adding log4j-spring-boot to your classpath, you just need to replace
${bundle:application:log.root.dir}
with
${spring:log.root.dir}

NPE on autowiring from dependent Project

This is my project structure,
Parent Projectt -->
pom.xml
(sub modules core,web,services)
core prj -->
pom.xml
web prj --> has core,services dependency and has ComponentScan for com.aaa.bbb
pom.xml
services prj --> has core, web dependency
pom.xml
client Project -->
pom.xml (sub modules xxx,yyy)
xxx -->
pom.xml
yyy --> has core dependency
pom.xml
xxx and yyy jars are used in core project and war is built by web project.
when i autowire services/repositories in yyy project i am getting NPE for services/repositories.
Can any one please let me know how i can autowire services/repositories in yyy project from core project services/repositories?
Thank you,
To be able to autowire the bean from library, you have two options:
If you have access to the library code (I think this is your case):
1.1 Add annotation to mark which class is bean (using #Component, #Service,...)
1.2 In your configuration class (class which have #Configuration or #SpringBootApplication or #ComponentScan...), add path of xxx and yyy project to the classpath
#Configuration
#ComponentScan("com.my.package.xxx,com.my.package.yyy")
public class YourApplication
If you don't have access to the library code
2.1 In your configuration class, create a #Bean annotated method and initialize your bean here.
#Bean
public XRepository getXRepository() {
return new XRepositoryImpl(); // Here is your initialization logic
}

Netbeans 8 won't reload static Thymeleaf files

I am using Spring Boot and Thymeleaf via Maven. I can't seem to get Netbeans to automatically re-deploy any of my Thymeleaf template files when I make changes. In order to see the changes I need to do a full clean/build/run. This takes way too long.
The templates are in src/main/resources/templates. I have an application.properties file in src/main/resources/ with spring.thymeleaf.cache=false and spring.template.cache=false.
I have "Compile on save", "Copy resources on save" and "Deploy on save" turned on in the project settings.
My maven build produces a war file that Netbeans deploys to Tomcat and I am using the annotation #EnableAutoConfiguration.
Netbeans does hot deploy changes to the Java classes but not for any of the static files in src/main/resources/.
Software in use:
Mac OS X 10.9.4
Java 1.8
Netbeans 8.0.1
Tomcat 8.0.12
Spring Boot 1.1.7
Thymeleaf 2.1.3 (via Spring Boot)
Any guidance is much appreciated.
An option would be to look into configuring Thymeleaf's FileTemplateResolver
To do that with Spring Boot, define a bean implementing the ITemplateResolver interface with the name defaultTemplateResolver, when present, Spring Boot would take it instead of its default, here is how that would be done, and assuming you have component scanning active so this configuration class will be picked up automatically:
#Configuration
public class ThymeleafConfiguration {
#Bean
public ITemplateResolver defaultTemplateResolver() {
TemplateResolver resolver = new FileTemplateResolver();
resolver.setSuffix(".html");
resolver.setPrefix("path/to/your/templates");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
resolver.setCacheable(false);
return resolver;
}
}
The prefix should be a relative path that when added to your runtime working directory (cwd), would resolve to the templates directory. If you are unsure, set that to the full absolute path, but then there would be no point of the above bean. Since setting the spring.thymeleaf.prefix property to an absolute path would probably have the same effect.
Have been looking for a solution to my eclipse+thymeleaf+sprint boot reloading templates dynamically for a log while....
Finally I found this question here and spring.thymeleaf.cache=false and spring.template.cache=false fixed my issue.
Besides setting the Thymeleaf views as non-cacheable by ie. spring.thymeleaf.cache=false in your application.properties,
try explicitly defining the resource directory in your pom.xml:
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
...
</build>
To deal with that, the spring-boot-maven-plugin in the pom.xml should seems like this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
</dependencies>
</plugin>
And add this to your application properties:
spring.thymeleaf.cache=false
It usually works to Spring beans too.
Just to say this works nicely for me using an external instance of Tomcat:
Run Tomcat with JRebel or Spring Loaded javaagent as a VM option
Turn off "Compile on save", "Copy resources on save" and "Deploy on save"
Add a custom action in Netbeans that executes the compile goal
Run that when you want to see an update
http://wiki.netbeans.org/MavenBestPractices#Binding_Maven_goals_to_IDE_actions
https://github.com/spring-projects/spring-loaded
https://zeroturnaround.com/software/jrebel/quickstart/standalone/
Or you can you use the embedded tomcat with spring-boot-maven-plugin and Spring Loaded instead, then you won't need the compile action:
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html
I had this problem too. I notice Netbeans reload automaticaly webpages that are in
/src/main/webapp/
You have to move all your templates from /src/main/resources/templates to this directory.
Also you have to change the spring boot property on application.properties file:
spring.thymeleaf.prefix=templates/
That works for me
I had this same issue on Netbeans 8.0.2 and Windows. I was building a WAR to be deployed to Tomcat, but I wanted to try out Spring Boot. It looks like newer versions of Netbeans might resolve this with the Spring Boot plugin or using Eclipse. It seemed nutty to swap IDEs over something tiny like this. I tried all of the suggestions I could find; spring loaded, caching properties, extending the TemplateResolver...I couldn't get any of them to work. I finally stumbled on this blog and following these instructions solved my issue.

Spring Boot Application not reading application.properties file when using Maven test

UPDATE:
I realized a couple of things now. My application.properties file is being loaded properly because I verified via the /env path (thanks Dave) that my DB properties are being loaded. The problem appears to be that when I run it using the Spring Boot maven plug-in, it fails to initialize my dataSource.
mvn spring-boot:run
This then causes my application to blow-up with errors because other beans can't get initialized. The odd thing is it runs fine from Eclipse.
I have a class called DataService that extends JdbcTemplate. In my DataService constructor, I inject the DataSource.
#Component
public class DataService extends JdbcTemplate {
#Autowired
public DataService(DataSource dataSource){
super(dataSource);
}
...more custom methods
}
I use this DataService class in other beans to perform DB operations. My DataSource is defined in my application.properties file
spring.datasource.url: jdbc:h2:tcp://localhost/~/testdb2
spring.datasource.driverClassName: org.h2.Driver
This is my Application.java class
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableWebMvcSecurity
#EnableAsync
#EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I first realized this when I was attempting to run jUnit tests from Maven using
mavent test
I thought it just had to do with how it was executing the jUnit test cases however it is also occurring when I simply try to run the application using maven.
My JUnit4 test class is defined as follows:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes={Application.class})
#WebAppConfiguration
public class QuestionRepositoryIntegrationTests {
...methods
}
I used the example from the Spring Boot how-to docs (https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html)
When I run this JUnit class from Eclipse, it works just fine. When it executes from maven, it starts to act up as I described above.
Try to define the <resources> tag in the build section in your pom, setting path for resource directory where is application.properties:
<build>
<resources>
<resource>
<directory>resources</directory>
<targetPath>${project.build.outputDirectory}</targetPath>
<includes>
<include>application.properties</include>
</includes>
</resource>
</resources>
</build>
You can configure your main datasource as the following, I'm using mysql here. But you can use your own datasource. you can configure the following in your application.properties inside src/main/resources
spring.datasource.url = jdbc:mysql://localhost:3306/dsm
spring.datasource.username = root
spring.datasource.password = admin123
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
To run test inside your application you can either use the same datasource or create application-test.properties inside src/test/resources and it's possible to configure test data source over there.
Just add the following statement;
#TestPropertySource("classpath:application.properties")
To your test class. I am assuming you have your application.properties file under src/test/resources
Here is my working example;
#RunWith(SpringJUnit4ClassRunner.class)
#TestPropertySource("classpath:application.properties")
public class TestTwitterFeedRoute extends CamelTestSupport {
//...
}
This works for me:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = TestApplication.class,
initializers = ConfigFileApplicationContextInitializer.class)
public class SomeTestClass {
...
}
Make sure your #ConfigurationProperties annotation is set to the same prefix as whatever you're using in your configuration file (application.config)
If you're using eclipse, its always a good idea to check the projects build resources. (Rclick project->properties->build path)
I was not getting my application.properties file picked up and turned out I simply missed adding it to build resources.
I'm trying to load all properties files form outside jar, below entry in pom works perfect, you can also exclude or include files depends upon requirements.
<build>
<resources>
<resource>
<directory>config</directory>
<includes>FILENAME</includes>
<excludes>FILENAME</excludes>
</resource>
</resources>
</build>

FileNotFoundException..Classpath resource not found in spring?

I have code like this in Main.java :
AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Until recently it was working, but I don't know why it started failing with the below exception:
Exception in thread "main"
org.springframework.beans.factory.BeanDefinitionStoreException:
IOException parsing XML document from
class path resource
[spring-config.xml]; nested exception
is java.io.FileNotFoundException:
class path resource
[spring-config.xml] cannot be opened
because it does not exist
the spring-config.xml is in src/main/resources folder.
Actually I wanted to learn about the annotations: #Postconstruct and #Predestroy, so I changed the build path to Jdk 1.6 from Jdk 1.5.
Since then the problem started...
Any clue why it is not working?
NOTE: If any wants to see my project structure please follow this link
http://code.google.com/p/javapracticeram/source/browse/trunk/SpringExample/
EDIT:
Looking at your classpath you exclude src/main/resources and src/test/resources:
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
Is there a reason for it? Try not to exclude a classpath to spring-config.xml :)
Check the contents of SpringExample/target/classes. Is spring-config.xml there? If not, try manually removing the SpringExample/target/ directory, and force a rebuild with Project=>Clean... in Eclipse.
This is due to spring-config.xml is not in classpath.
Add complete path of spring-config.xml to your classpath.
Also write command you execute to run your project. You can check classpath in command.
Two things worth pointing out:
The scope of your spring-context dependency shouldn't be "runtime", but "compile", which is the default, so you can just remove the scope line.
You should configure the compiler plugin to compile to at least java 1.5 to handle the annotations when building with Maven. (Can also affect IDE settings, though Eclipse doesn't tend to care.)
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
After that, reconfiguring your project from Maven should fix it. I don't recall exactly how to do that in Eclipse, but you should find it if you right click the project node and poke around the menus.
I was getting the same problem when running my project. On checking the files structure, I realised that Spring's xml file was inside the project's package and thus couldn't be found. I put it outside the package and it worked just fine.
Best way to handle such error-"Use Annotation".
spring.xml-<context:component-scan base-package=com.SpringCollection.SpringCollection"/>
add annotation in that class for which you want to use Bean ID(i am using class "First")-
#Component
public class First {
Changes In Main Class**-
ApplicationContext context =
new AnnotationConfigApplicationContext(First.class);
use this.

Resources