I'm stuck with the following problem. My application doesn't create my Services at startup and I end up with a NullPointerException when I try to use them in my Maven Tests after Inject them with #Autowired.
I don't understand where it comes from. I have done some research but I still don't understand why it doesn't work.
Here is the class where my Autowired administrationActionService is null:
public class AdministrationActionTests extends EntityTests {
#Autowired
AdministrationActionService administrationActionService;
#Test
public void equalsTests() {
administrationActionService.getExample();
[...]
The class :
package com.bloombooking.services;
#org.springframework.stereotype.Service
public class AdministrationActionService extends ServiceEntity{
#Autowired private AdministrationActionDao administrationActionDao;
[...]
And my ApplicationContext.xml. I've placed it in src/ApplicationContext.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"
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:component-scan base-package="com.bloombooking.services, com.bloombooking.dao"/>
</beans>
I really don't know what I could have done wrong. Can someone help me? Thanks!
To make it work you have to make the following changes:
add #RunWith(SpringJUnit4ClassRunner.class) to your class.
add #ContextConfiguration("path_to_you_spring_beans.xml")
So your class becomes:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("path_to_you_spring_beans.xml")
AdministrationActionTests {
}
Related
I have an application based on MVC and I want to log inputs/outputs from all my controllers.
Also, each of my controller methods is annotated with some specific annotation (eg: #MyControllerMethod).
I wrote an Annotated Aspect which works fine when I use the annotation (eg: LogRequestReply) from the aspect on my controller methods.
#Around("#annotation(com.xyz.LogRequestReply)")
public Object logRequestResponse(ProceedingJoinPoint pjp) throws Throwable {
#MyControllerMethod
#LogRequestReply /* It invokes my logRequestResponse method */
public ResponseEntity controllerMethodA(...) {}
However, I have a lot of controller methods and each with annotation MyControllerMethod.
Is there a way I can make my aspect annotation make work on all controller methods by default, such that each of the methods automatically calls my aspect logger and I can log the inputs/outputs?
Note:
I also looked into writing an interceptor extending from HandlerInterceptorAdapter. But it has its own complexity of being able to log request/response where the stream can only be read once.
Please suggest.
One option is to let the #Around definition less restrictive, add a restriction by package or something like that.
Internally you can check if this is a Controller by this check bellow and then print the request/response:
#Pointcut("within(com.mypackage.controller..*)")
private void inControllerPackage() {
}
#Around("inControllerPackage()")
public Object logRequestResponse(ProceedingJoinPoint pjp) throws Throwable {
if (pjp.getSignature().getDeclaringType().isAnnotationPresent(RestController.class)) {
...
}
Perhaps you should include the AOP in your controller-config
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
<mvc:default-servlet-handler />
<context:component-scan base-package="com.xyz.controller" />
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="whatever" class="com.xyz.controller.MyRestController"/>
</bean>
and in your Aspect you can also include the within combined with annotation:
#Around(value = "#within(com.xyz.server.annotation.MyAnnotationForController) || #annotation(com.xyz.server.annotation.MyAnnotationForController)")
public Object ownersTimeZone(ProceedingJoinPoint joinPoint) throws Throwable {
//whatever you need before
Object obj = joinPoint.proceed();
//whatever you need after
return obj;
}
I am new to Spring as I inherited an existing project at work that was developed by another company using Spring 3.2.18, and I have come across the following problem:
I am working on application A (app A does not run on a web server), which uses as a dependency project B. I have the source code of B so I build it and include the jars as a maven dependency. Project B contains Class_1, Interface_2 and Class_2 (which implements Interface_2). Class_1 is in org.foo while Interface_2 and Class_2 is in org.toot.
In application A I need to Autowire Class_1 in a TestClass like this:
TestClass.java
#ContextConfiguration(locations={"file:src/test/spring/app-beans.xml"})
public class TestClass{
#Autowired
Class_1 class1;
// do stuff
}
app-beans.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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
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
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:spring-configured />
<context:annotation-config />
<aop:aspectj-autoproxy />
<context:component-scan base-package="org.foo" />
<context:component-scan base-package="org.toot" />
<bean id="class_1" primary="true" class="org.foo.Class_1"/>
</beans>
Now the thing is that Class_1 in project B also has an autowired field:
Class_1.java
#Service
public class Class_1 {
#Autowired
Interface_2 int2;
}
Interface_2.java
public interface Interface_1 {
// stuff
}
Class_2.java
#Service
public class Class_2 implements Interface_2{
// stuff
}
Whenever I try to run my TestClass I get the following error:
Could not autowire field: private org.foo.Class_1;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.toot.Interface_1]
found for dependency [...]: expected at least 1 bean which qualifies as autowire candidate for this dependency.
What I get from it is that it somehow tries to autowire Class_1 but cannot autowire Interface_2 so it fails. How can I get the implementation of Interface_2 (Class_2) autowired to the field of Class_1? Project B does not have any spring-context files. Can I modify my app-beans.xml in project A to achieve it? Would I have to include context files in project B and re-build? Please share your knowledge and thank you for reading.
I have a web application which is supposed to run a scheduled code:
package com.myproject.daemon.jobs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class MyDaemonJob {
private static final Logger log = LoggerFactory.getLogger(MyDaemonJob.class);
#PostConstruct
public void init() {
log.info("MyDaemonJob is intialized " );
}
#Scheduled(fixedDelay = 1000)
public void startDaemon() {
try {
log.info("MyDaemonJob is running ...");
} catch (Exception e) {
log.error("Encountered error running scheduled job: " + e.getMessage());
}
}
}
It surely is recognized as a Spring bean and initialized, as I can see from the PostConstruct log. However the method with the #Scheduled annotation never runs although it is supposed to run every 1 second.
Here is app context 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"
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-4.0.xsd">
<context:component-scan base-package="
com.myproject.daemon.jobs,
com.myproject.product" />
</beans>
Thank you ALL for quick help. This is really helpful.
The code started working, once I added config class with annotations as shown below --
package com.myproject;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
#Configuration
#EnableScheduling
public class AppConfig {
// various #Bean definitions
}
To use the #scheduled annotation it is necessary to include the spring task name space in spring bean configuration xml file. You can update the following namespac e in your xml configuration file.
<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:task="http://www.springframework.org/schema/task"
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-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd">
Otherwise if you use the spring-boot application you can include the #EnableScheduling in your configuration file
I have a context as follows
<?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:int="http://www.springframework.org/schema/integration"
xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/amqp
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<int:gateway id="fooGateway" service-interface="com.foo.FooGateway" />
</beans>
My gateway interface is as follows:
public interface FooGateway
{
public void foo(String foo);
}
This context is imported into another context but the fooGateway bean is never created by GatewayProxyFactoryBean.
I've set a breakpoint in GatewayProxyFactoryBean and I can see that it is not creating a proxy for this interface.
Turn on DEBUG logging for org.springframework; the bean creation process emits lots of information including when it reads particular configuration files.
I would like to unit test one validator class in Spring. There are 6 other existing validator classes but they don't have unit tests so I only want to test my validator class.
My problem is that when I run my unit test (which tests only my class) "somehow" an other validator class is being tested... (it doesn't have unit test).
Is it possible that this is the default behaviour of the LocalValidatorFactoryBean to scan all the validator classes and to run their isValid method?
Can I specify the validator classes somehow that have to be tested? Like defining a ConstraintValidatorFactory?
Java test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"/applicationContext-test-validator.xml"})
public class MyValidatorTest {
#Autowired
private Validator validator;
#Test
public void testIsValid_true() {
...
Set<ConstraintViolation<Record>> violations = validator.validate(data);
...
}
}
application context 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
</beans>
Thanks,
V.