Autowired object is null in Rest controller when deployed on JBoss EAP - spring

I am using Springboot and RESTEasy to create a small webapp, in my Controller class I am doing #Autowire for my Dao class. Whenever I deploy the code, the dao reference variable always ends up with null value. I have used #Component for controller and in mail Application class I have used #SpringBootApplication and at my dao class also I have added #Repository and #Service.
Please give some suggestions where exactly i am doing wrong?
Note: Works fine if I run it as a standalone Springboot app. But this issue occurs when deploy in JBoss server.
Code format is displayed below: While debugging, at line , List<DataDto> dataList = dao.findData(); always dao is null, because of which API call fails.
#Component
#Path("/")
public class apiController {
#Autowired
private ApiDao dao;
public void setApiDao(ApiDao dao) {
this.dao = dao;
}
#GET
#Path("/getData")
#Produces(MediaType.APPLICATION_JSON)
public List<DataDto> getDetails(){
List<DataDto> dataList = dao.findData();
return logList;
}
}
Dao class code is as below:
#Repository
#Service
public class ApiDao {
private final Logger log = LoggerFactory.getLogger(ApiDao.class);
private JdbcTemplate jdbcTemplate;
#Autowired
public ApiDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<SystemEntity> findData() throws SystemException{
return entityList;
}
}
And for configuration i have used below code and in pom.xml added required dependencies:
#Component
#ApplicationPath("/rest/")
public class JaxrsApplication extends Application {
}

The Problem
JBoss provides inbuilt support for RESTEasy. So in this case the apiController is initialized twice:
Once by Spring
Once by JBoss.
The autowiring happens under the hood in the instance initialized by spring but when a call is triggered to the apiController it is handled by the instance initialized by JBoss.
Solution
Disable JBoss from initializing RESTEasy Controllers. In your spring boot application create a web.xml under src/main/webapp/WEB-INF and add the following context parameters:
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.providers</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.resources</param-name>
<param-value>false</param-value>
</context-param>

Related

Run Spring-Enabled #Component Method on Tomcat Startup

My SpringMVC application runs in Tomcat. I have a Spring-enabled #Component with a method that needs to execute just once on Tomcat startup. It's a method to go into the Service/DAO layer and send an email.
Normally, the way to do a Tomcat Startup Java class call is in web.xml as a Servlet with load-on-startup (link).
<servlet>
<servlet-name>StartupEmail</servlet-name>
<servlet-class>com.app.StartupEmail</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
But that Servlet won't have access to my Spring layer with dependencies.
public class StartupEmail extends HttpServlet {
..
}
I can also have Cron-based Scheduled Jobs in SpringMVC, but they are time-based rather than on Tomcat Startup.
#Component
public class StatusScheduleJob {
#Autowired
private MyService myService;
#Scheduled(cron = "${statusjob.cron.expression}")
public void changeStatuses() {
myService.execute(); //...
}
}
statusjob.cron.expression=0 0 * * * *
So is there a good solution here?
If I understand the problem, there are several options depending on when exactly the startup code needs to be executed:
Javax #PostConstruct annotation on a bean
Implementing the InitializingBean interface
Implementing the ApplicationListener interface for ContextRefreshedEvent
Implementing the Spring CommandLineRunner interface
Here are a few references to learn about these options and more:
https://www.baeldung.com/running-setup-logic-on-startup-in-spring
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/CommandLineRunner.html
https://docs.oracle.com/javaee/7/api/javax/annotation/PostConstruct.html

propleme with the injection of dependence of spring

For the project that we create during my formation we use spring to make dependency injection.
we have a servlet-context.xml file with the following configuration:
<context:component-scan base-package="fr.autoquiz3000" />
I created several controllers and I have no problem injecting the dao for example:
package fr.autoquiz3000;
#Controller
#RequestMapping("/public")
public class PublicController {
#Autowired
private UserDao uDao;
#GetMapping("/connection")
public ModelAndView getConnection() {
return new ModelAndView("public/viewConnexion");
}
but I try to create a filter with a dao like this:
package fr.autoquiz3000;
#Component
public class CountQuizStudent implements Filter {
#Autowired
private QuizToDoDao qtdDao;
and I have this error:
qtdDao= null
java.lang.NullPointerException
at fr.autoquiz3000.CountQuizStudent.doFilter(CountQuizStudent.java:41)
Someone could explain to me what I'm doing wrong!
thank you!
For filters override init method and set Spring beans there:
#Override
public void init(FilterConfig filterConfig) throws ServletException {
WebApplicationContext springContext =
WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
userDao = springContext.getBean(UserDao.class);
}
or use DelegatingFilterProxy:
<filter>
<filter-name>yourFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>yourFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
#Component("yourFilter")
public class YourFilter implements Filter {
// auto wiring available as it's just Spring Bean
}

Spring not autowiring service or throwing exception

I am trying to autowire a service which is a proxy into a static class. Spring is not cooperating and it's not giving any indication of whats wrong.
I can only see:
Method threw 'org.springframework.beans.factory.BeanCreationException' exception. Cannot evaluate com.domain.services.SessionService$$EnhancerBySpringCGLIB$$f94406f3.toString()
in the debugger when I try to evaluate the variable.
I have a utility class for my controllers:
public class ControllerUtil {
private static SessionService sessionService;
public ControllerUtil(SessionService sessionService) {
this.sessionService = sessionService;
}
At application startup I try to add the sessionService to the static class. The session service is in session scope so I am trying to add the proxy here.
#Configuration
public class BeanConfig {
#Autowired
SessionService sessionService;
#PostConstruct
private void initStaticClasses() {
/*
* Need to add proxy to controller utils
* */
new ControllerUtil(sessionService);
}
Finally my SessionService class:
#Service
#Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionService {
#Autowired
BusinessDAO businessDAO;
Business business = businessDAO.getBusinessById("1");
public SessionService() {
System.out.println("New session service");
}
I am just trying to hardcode in the Business for dev purposes.
Spring must be failing somewhere but I'm not getting anything back in the logs and debugging isn't really helping.
Can anyone advise what I've done wrong?
Thanks
Add this line in your web app initializer if you are using java configuration.
servletContext.addListener(new RequestContextListener());
If you are using spring xml configuration add following in web.xml
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

GWTP using Spring in server side

I am working with gwtp and I would like to use Spring on the server side. I have seen that Spring is include in gwtp, but I don't know how I can use it. Anyone can help me about that?
Will be cool some example.
I have looked for by google, but no way :(
Thanks a lot!!
GWTP is using GIN pattern (Dependency Injection at Client Side) and it's default integration with GUICE at DI server side. for more detail GWTP
Spring is server side DI pattern.
I have seen that Spring is include in gwtp,
It does not include Spring at all. it's default integration with GUICE. but you can use spring with it.
gwtp-sample-basic-spring example
Well, at first you have to configure Spring in your web.xml descriptor:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<servlet-class>org.spring4gwt.server.SpringGwtRemoteServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<url-pattern>/yourProjectName/springGwtServices/*</url-pattern>
</servlet-mapping>
Notice that you need the Spring4GWT library for this example.
Next, in your RemoteService interfaces you need to specify the RemoteServiceRelativePath like this example:
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.google.gwt.user.client.rpc.RemoteService;
#RemoteServiceRelativePath("springGwtServices/userService")
public interface UserService extends extends RemoteService{
public User getUserByLogin(String name);
public void logout();
public void deleteUserById(Long userId);
}
And now, you just need to implement your service as in any Spring app.
Example, suppose you want an action to delete a User by ID and using the GWTP paradigm:
In server side, here is the Handler:
#Repository("deleteUserHandler")
public class DeleteUserHandler extends AbstractActionHandler<DeleteUserAction, DeleteUserResult> {
#Autowired
private UserService userService;
public DeleteUserHandler(){
super(DeleteUserAction.class);
}
#Override
public DeleteUserResult execute(DeleteUserAction action, ExecutionContext arg1)
throws ActionException {
Long idToDel = action.getUserToDeleteId();
if(idToDel != null){
userService.deleteUserById(idToDel);
}
return new DeleteUserResult();
}
#Override
public void undo(DeleteUserAction arg0, DeleteUserResult arg1,
ExecutionContext arg2) throws ActionException {
// TODO Auto-generated method stub
}
}
The DeleteUserAction is as follows
public class DeleteUserAction extends UnsecuredActionImpl<DeleteUserResult> {
private Long userToDeleteId;
public DeleteUserAction(Long userToDel) {
this.userToDeleteId = userToDel;
}
/**
* For serialization only.
*/
#SuppressWarnings("unused")
private DeleteUserAction() {
}
public Long getUserToDeleteId() {
return userToDeleteId;
}
public void setUserToDeleteId(Long userToDeleteId) {
this.userToDeleteId = userToDeleteId;
}
}
And finally the Result class:
public class DeleteUserResult implements Result {
/**
* For serialization only.
*/
//#SuppressWarnings("unused")
public DeleteUserResult() {
}
}
I hope this helps.
PS: I suppose you can do the Spring things (application context etc..) by yourself, if not, please tell
You can find some good examples on GWTP repository in Github. We recently migrated all of our from Google Code to Github, which hosts the latest version.
Remember you can also use REST communication using the new GWTP-Dispatch-Rest, with that you don't need a lot of configuration code to integrate GWTP with Spring server side.
https://github.com/ArcBees/GWTP-Samples

init a spring bean from web.xml

I am updating an existing Java EE web application that uses Spring.
In my web.xml, there is a servlet defined as follows:
<servlet>
<display-name>My Example Servlet</display-name>
<servlet-name>MyExampleServlet</servlet-name>
<servlet-class>com.example.MyExampleServlet</servlet-class>
</servlet>
now, in this class I need to add an #Autowite annotation:
class MyExampleServlet extends HttpServlet {
#Autowired (required = true)
MyExampleBean myExampleBean;
[...]
}
the problem is that MyExampleBean is initialized by the Application Server
(in my case, weblogic.servlet.internal.WebComponentContributor.getNewInstance...)
so, Spring is not aware of that, and Spring does not have a chance to wire "myExampleBean".
How to solve that?
that is, how I need to modify web.xml or MyExampleServlet so that MyExampleServlet gets the reference to myExampleBean?
A possibility would be to add this init code inside MyExampleServlet,
but it requires a reference to servletContext. How to get a reference to servletContext?
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
myExampleBean = (MyExampleBean) context.getBean("myExampleBean");
I see, HttpServlet/GenericServlet has a getServletContext() method,
(and the application server calls first the servlet's init(ServletConfig config), and config contains a reference to servletContext).
See http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/GenericServlet.html
The code modified:
class MyExampleServlet extends HttpServlet {
MyExampleBean myExampleBean;
#Override
public void init() throws ServletException {
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
myExampleBean = (MyExampleBean) context.getBean("myExampleBean");
}
[...]
}
in your application context xml, you need something like
<bean id="myExampleBean" class="path/to/myExampleBean">

Resources