I hope someone can help me, I am starting to work with Spring MVC.
I have a java spring MVC web application with this packages: com.app.controller, com.app.modelo, com.app.servicio, y com.app.repositorio. In the repositorio package I have the UsuarioRepositorio interface, in the servicio package I have the UsuarioServicio class. The controller uses the UsuarioServicio class and this one uses de UsuarioRepositorio interface. The controller initializes the UsuarioServicio object in it´s constructor. When running the project it shows this error:
The module has not been deployed.
See the server log for details.
[Payara 5.2021.10] [GRAVE] [] [javax.enterprise.system.core] [tid: _ThreadID=90 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1643303084394] [levelValue: 1000] [[
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.NoSuchMethodException: com.app.controller.UsuarioController.()]]
UsuarioRepositorio interface
package com.app.repositorio;
import com.app.modelo.UsuarioModelo;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UsuarioRepositorio extends JpaRepository<UsuarioModelo, Integer>{
Optional<UsuarioModelo> porUsuario(String CodigoUsuario);
Optional<UsuarioModelo> porUsarioEstatus(String CodigoUsuario, boolean EstatusLogeado);
Optional<UsuarioModelo> porUsuarioIntentos(String CodigoUsuario, int CantidadIntentos);
}
UsuarioServicio class
package com.app.servicio;
import com.app.modelo.UsuarioModelo;
import com.app.repositorio.UsuarioRepositorio;
import org.springframework.stereotype.Service;
#Service
public class UsuarioServicio {
private final UsuarioRepositorio repouser;
public UsuarioServicio(UsuarioRepositorio ru){
repouser = ru;
}
public UsuarioModelo registrarUsuario (String usuario){
if (usuario == null){
return null;
}else{
UsuarioModelo usermodel = new UsuarioModelo();
usermodel.setCodigoUsuario(usuario);
return repouser.save(usermodel);
}
}
public UsuarioModelo autentica(String usuario){
return repouser.porUsuario(usuario).orElse(null);
}
}
Controller
package com.app.controller;
import com.app.modelo.UsuarioModelo;
import com.app.servicio.UsuarioServicio;
import com.app.repositorio.UsuarioRepositorio;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class UsuarioController {
private UsuarioServicio userserv;
public UsuarioController(UsuarioServicio us){
userserv = us;
}
#GetMapping("/index")
public String getLoginPage(Model modelo) {
modelo.addAttribute("loginrequest", new UsuarioModelo());
return "index";
}
#PostMapping("/index")
public String login(#ModelAttribute UsuarioModelo usermod){
UsuarioModelo logeduser = userserv.autentica(usermod.getCodigoUsuario());
logeduser = logeduser == null ? userserv.registrarUsuario(usermod.getCodigoUsuario()) : logeduser;
return logeduser == null ? "error_page" : "redirect:/index";
}
}
I think the error could be due to a misconfiguration of the dispatcher-servlet.xml file because I remove the UsuarioServicio from the controller and the application runs perfectly
dispatcher-servlet.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">UsuarioController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />-->
<bean name="UsuarioController" class="com.app.controller.UsuarioController"/>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!--bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" /-->
<!-- ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) -->
</beans>
application.properties
spring.datasource.url=jdbc:sqlserver://XXXXXX;databaseName=XXXXX
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.username=XXXXXX
spring.datasource.password=XXXXXX
spring.jpa.properties.hibernate.dialeg = org.hibernate.dialect.sqlserver
I modified the dispatcher-servlet like this:
<bean name="UsuarioController"
class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio"
value="us"/>
</bean>
Now the error is this:
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'UsuarioController' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [com.app.servicio.UsuarioServicio]: Failed to convert value of type 'java.lang.String' to required type 'com.app.servicio.UsuarioServicio'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.app.servicio.UsuarioServicio': no matching editors or conversion strategy found]]
I have updated the dispatcher-servlet.xml file like this
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us"/>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio" ref="UsuarioServicio" />
</bean>
and like this
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us"/>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg ref="UsuarioServicio" />
</bean>
Both cases the error is noew this
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.NoSuchMethodException: com.app.servicio.UsuarioServicio.()]]
I modified the dispatcher-servlet like this:
<jpa:repositories base-package="com.app.repositorio"/>
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us">
<constructor-arg ref="UsuarioRepositorio"/>
</bean>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio" ref="UsuarioServicio" />
</bean>
And I got this error
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.xml.sax.SAXParseException; lineNumber: 36; columnNumber: 59; El prefijo "jpa" para el elemento "jpa:repositories" no está enlazado.]]
Then I removed de prefix "jap" like this
<repositories base-package="com.app.repositorio"/>
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us">
<constructor-arg ref="UsuarioRepositorio"/>
</bean>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio" ref="UsuarioServicio" />
</bean>
and the error is this
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.xml.sax.SAXParseException; lineNumber: 36; columnNumber: 55; cvc-complex-type.2.4.a: Se ha encontrado contenido no válido a partir del elemento 'repositories'. Se esperaba uno de '{"http://www.springframework.org/schema/beans":import, "http://www.springframework.org/schema/beans":alias, "http://www.springframework.org/schema/beans":bean, WC[##other:"http://www.springframework.org/schema/beans"], "http://www.springframework.org/schema/beans":beans}'.]]
I did some research and found some configurations to do in the dispatcher-servlet
dispatcher-servle.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/data/jpa https://www.springframework.org/schema/data/jpa/spring-jpa-2.6.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-5.3.xsd" >
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<mvc:annotation-driven conversion-service="UsuarioServicio"/>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">UsuarioController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />-->
<context:component-scan base-package="com.app.repositorio" />
<jpa:repositories base-package="com.app.repositorio"/>
<bean id="UsuarioRepositorio" class="com.app.servicio.UsuarioServicio" >
</bean>
<bean id="UsuarioServicio" class="com.app.servicio.UsuarioServicio">
<constructor-arg name="ur" ref="UsuarioRepositorio"/>
</bean>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg ref="UsuarioServicio"/>
</bean>
</beans>
now the error seems to be with this line <context:component-scan base-package="com.app.repositorio" />
org.xml.sax.SAXParseException; lineNumber: 46; columnNumber: 54; cvc-complex-type.2.4.c: El comodín coincidente es estricto, pero no se ha encontrado ninguna declaración para el elemento 'context:component-scan'.
I added this line #ComponentScan(basePackages = { "com.app.repositorio" }) to the UsuarioRepositorio interface, now the file is this
UsuarioRepositorio interface
package com.app.repositorio;
import com.app.modelo.UsuarioModelo;
import java.util.Optional;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
#ComponentScan(basePackages = { "com.app.repositorio" })
public interface UsuarioRepositorio extends JpaRepository<UsuarioModelo, Integer>{
Optional<UsuarioModelo> porUsuario(String CodigoUsuario);
Optional<UsuarioModelo> porUsarioEstatus(String CodigoUsuario, boolean EstatusLogeado);
Optional<UsuarioModelo> porUsuarioIntentos(String CodigoUsuario, int CantidadIntentos);
}
Corrections
The below corrections are ordered from lower level layers to higher level ones.
Correction #1: Persistence layer: Activate the Spring Data JPA repository bean support
Add the jpa XML namespace:
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
Update the xsi:schemaLocation XML schema location by adding the following:
http://www.springframework.org/schema/data/jpa https://www.springframework.org/schema/data/jpa/spring-jpa.xsd
Then add the repositories element:
<jpa:repositories base-package="com.app.repositorio" />
As a result:
Each bean is registered under a bean name that is derived from the interface name, so an interface of UserRepository would be registered under userRepository.
— Spring Data JPA - Reference Documentation.
Therefore, this should provide the usuarioRepositorio bean for our case.
For more details and a complete example, please, see the page: Spring Data JPA - Reference Documentation.
Correction #2: Application service layer: Add UsuarioServicio bean
Use the reference to the usuarioRepositorio bean for the usuarioServicio bean.
<bean id="usuarioServicio" class="com.app.servicio.UsuarioServicio">
<constructor-arg ref="usuarioRepositorio" />
</bean>
Please, note the case used for the id and ref attribute values: usuarioServicio, usuarioRepositorio.
Correction #3: Integration layer: Update UsuarioController bean
Use the reference to the usuarioServicio bean for the usuarioController bean.
<bean id="usuarioController" class="com.app.controller.UsuarioController">
<constructor-arg ref="usuarioServicio" />`
</bean>
Please, note the case used for the id and ref attribute values: usuarioController, usuarioServicio.
Related
I have the following error when I try to acces into main page
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userJpaRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'net.codejava.spring.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true), #org.springframework.beans.factory.annotation.Qualifier(value=userJpaRepository)}
In my UserController I have the following code
#Controller
public class UserController {
private UserService employeeServiceImpl;
#RequestMapping("/")
public String employee() {
this.employeeServiceImpl.listAlUsers();
return "employee";
}
#Autowired(required = true)
public void setEmployeeService(UserService employeeServiceImpl) {
this.employeeServiceImpl = employeeServiceImpl;
}
}
My UserService
public interface UserService {
public abstract List<User> listAlUsers();
public abstract User addUser(User user);
public abstract int removeUser(int id);
public abstract User updateUser(User user);
}
My UserServiceImpl
#Service("userService")
public class UserServiceImpl implements UserService {
#Autowired
#Qualifier("userJpaRepository")
private UserRepository userJpaRepository;
#Override
public List<User> listAlUsers() {
return userJpaRepository.findAll();
}
#Override
public User addUser(User user) {
return userJpaRepository.save(user);
}
#Override
public int removeUser(int id) {
userJpaRepository.delete(id);
return 0;
}
#Override
public User updateUser(User user) {
return userJpaRepository.save(user);
}
}
My JpaRepository
#Repository("userJpaRepository")
public interface UserRepository extends JpaRepository<User,Serializable> {
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
My servlet-context
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--The <context:component-scan...> tag will be use to activate Spring MVC annotation scanning capability which allows to make use of annotations like #Controller and #RequestMapping etc.-->
<!--Step 1 : HandlerMapping -->
<context:component-scan base-package="com.loiane.controller" />
<!--JPA Repository-->
<jpa:repositories base-package="com.loiane.repository.EmployeeJpaRepository"/>
<mvc:annotation-driven />
<!--Step 3 : View Resolver-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!--Bundles-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>messages</value>
</property>
</bean>
<!--Declaramos el interceptor para permitir el cambio de idioa en tiempo de ejecucion-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
<!--Si el idioma no existe cargamos el en-->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="lang" />
<property name="defaultLocale" value="en" />
</bean>
</beans>
The root-context is empty.
I don't know where is the possible cause of error I try to find differents options , but If I use the DAO pattern I receive the same error , so I would to know which is to problem to try to solve it.
The configuration of the project is with xml but I think there is not important to solve this situation.
Regards !
You are using bean qualifier name on repository interface #Repository("userJpaRepository"). Qualifier names are useful if more than 1 class is implementing the common interface. It helps to resolve the specific bean, which is to be autowired to other bean's interface variable. Declaring it on an interface will defeat its purpose. Removing the qualifier name should work if no other class (other than spring created proxy bean whose name would be userRepositoryImpl) is implementing UserRepository interface.
#Autowired
private UserRepository userJpaRepository;
And replace the Serializable with the Datatype of the ID column like Integer or Idclass.
#Repository
public interface UserRepository extends JpaRepository<User,Integer> {
}
Now to enable spring to scan for the interface that extent its predefined repository interfaces, add package to scan for in your spring context
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="net.codejava.spring.repository"/>
In my case it was a problem with incorrect User import (instead of import a User entity that I've created manually - I've imported another User).
I've changed import org.springframework.security.core.userdetails.User;
to import org.springframework.data.jpa.repository.JpaRepository;
My spring library : 3.2.0
Xml file :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<bean id = "res_Bean" class = "Restaurant"
<property name="welcomeNote" value="welcome to my restaurant"/>
</bean>
</beans>
Im trying to solve , but im not getting correct ans.
Exception in thread "main" java.lang.IllegalStateException:BeanFactory
not initialized or already closed - call 'refresh' before accessing
beans via the ApplicationContext at
org.springframework.context.support.AbstractRefreshableApplicationContext.getBeanFactory(AbstractRefreshableApplicationContext.java:172)
at
org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)
at TestSpring.main(TestSpring.java:12)
When you define bean attribute class should be equals to full package path of the class.
For example
<bean id="restaurant" class="com.models.Restaurant">
<property <property name="welcomeNote" value="welcome to my restaurant"/>>
</bean>
Is there anyway to get beans loaded via <context:component-scan/> in a xml file to be proxy'ed by an #Coniguration annotated class which has #EnableCaching and declares the SimpleCacheManager? This would be the easiest route for the large applicaiton I'm working with, my ultimate preference would be to convert it all over to a Configuration class, but that is a lot more work and there are next to no unit tests for this application -.- , something would totally break. The other option is to declare the Cache's in the xml which works fine but I feel like is a step backwards.
NOTE: The <context:annotation-config/> is declared in a separate xml file 'integration.xml' I put it back in the applicationContext.xml but it didn't affect anything.
The declaration of the caches and the enabling of the caching via #EnableCaching was moved to the below java class some time ago and I don't think anyone noticed that it stopped working. So I would like to get it working again in the best way.
Application Context (edited for brevity)
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
"
>
<util:properties id="properties" location="classpath:config.properties"/>
<context:property-placeholder properties-ref="properties"/>
<!-- TODO: Replace this with MethodInvokingBean - we don't actually *want* a ConfigFactory instance -->
<bean id="configFactory" class="net.adl.service.ConfigFactory">
<property name="properties" ref="properties" />
</bean>
<!-- Enable Caching -->
<cache:annotation-driven proxy-target-class="true"/>
<!-- Declaring the cache manager and caches here works, but I feel is a step backwards to put them back in the XML config -->
<context:component-scan base-package="
net.adl.quartz,
net.adl.config,
net.adl.dao,
net.adl.service,
net.adl.audit,
net.adl.diagnostic,
net.adl.loader,
net.adl.loader"/>
<!-- add support for #Scheduled -->
<task:scheduler id="taskScheduler" pool-size="10"/>
<task:executor id="taskExecutor" pool-size="10"/>
<!-- Used for real time monitoring of folders for data loads -->
<task:executor id="realTimeAutoLoaderExecutor" pool-size="1"/>
<task:annotation-driven scheduler="taskScheduler" executor="taskExecutor"/>
<!-- enable #Transactional annotations -->
<bean id="transactionAdvice" class="net.adl.aop.TransactionAdvice"/>
<!--<bean id="profiler" class="net.adl.util.Profiler"/>-->
<aop:aspectj-autoproxy proxy-target-class="true">
<aop:include name="transactionAdvice"/>
<!--<aop:include name="profiler"/>-->
</aop:aspectj-autoproxy>
<!-- set system properties -->
<bean id="systemPrereqs" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<!--
"systemProperties" is predefined; see:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html#expressions-beandef-xml-based
-->
<property name="targetObject" value="#{#systemProperties}"/>
<property name="targetMethod" value="putAll"/>
<property name="arguments">
<util:properties>
<prop key="net.sf.ehcache.skipUpdateCheck">true</prop>
<prop key="org.terracotta.quartz.skipUpdateCheck">true</prop>
</util:properties>
</property>
</bean>
<!-- Exception translation bean post processor -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>
<bean id="versionInfo" class="net.adl.util.VersionInfo">
<property name="versionFilePath" value="${labmatrix.home}/version-info.txt"/>
</bean>
<!-- Here is where we call in the <context:annotation-config/>, not sure why its done in a separate file -->
<import resource="resources/spring/integration.xml"/>
</beans>
Integration.xml -- I think the idea is more deployment specific config options can go in this one
<?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-3.1.xsd
"
>
<context:annotation-config/>
</beans>
MethodCachingConfiguration Class
package net.adl.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
#Configuration
#EnableCaching
public class MethodCacheConfiguration {
public static final String STUDY_CONFIG = "config.studies";
public static final String ACCESS_CONFIG = "config.access";
public static final String WORKFLOW_CONFIG = "config.workflows";
public static final String PROCESS_CONFIG = "config.processes";
public static final String QUERY_CONFIG = "config.queries";
public static final String AUTOLOADER_CONFIG = "config.autoloader";
public static final String LOCALIZATION = "localization";
public static final String FACTORY_CONFIG = "config.factories";
/**
* Configures the cacheManager bean for #Cacheable annotation support
*/
#Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(
new ConcurrentMapCache(STUDY_CONFIG),
new ConcurrentMapCache(ACCESS_CONFIG),
new ConcurrentMapCache(WORKFLOW_CONFIG),
new ConcurrentMapCache(PROCESS_CONFIG),
new ConcurrentMapCache(QUERY_CONFIG),
new ConcurrentMapCache(AUTOLOADER_CONFIG),
new ConcurrentMapCache(LOCALIZATION),
new ConcurrentMapCache(FACTORY_CONFIG)
));
return cacheManager;
}
}
EDIT: Fixed copy paste reformat typos
<cache:annotation-driven /> and #EnableCaching are equal you can have only one (maybe it can be source of your trouble) Can you provide example of code where you are actually using caching? Which bean should use cache feature.
Answer provided by chalimartines
I am using SpringMVC 3 with Annotated Controllers. I successfully mapped my URL ("/HelloWorld) to a Controller and defined its GET processing method.
The error is that upon typing the (App)/HelloWorld URL, my web server (GlassFish) gives this error:
The requested resource is not available.
But in the GlassFish log I see that the URL was mounted.
Mapped "{[/HelloWorld],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView controllers.HelloWorldController.processHelloWorld()
My Files:
(1) HelloWorldController.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
*
* #author */
#Controller
#RequestMapping("/HelloWorld")
public class HelloWorldController {
#RequestMapping(method = RequestMethod.GET)
public ModelAndView processHelloWorld()
{
ModelAndView model = new ModelAndView("HelloWorldPage");
model.addObject("msg", "Expanded string - hello world");
return model;
}
}
(2) Dispatcher-Servlet.xml. Note the MVC-Annotation-Driven approach. The indexController is not used.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="controllers" />
<mvc:annotation-driven />
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
(3) HelloWorldPage.jsp:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<h1>Spring MVC Hello World Annotation Example</h1>
<h2>${msg}</h2>
</body>
</html>
Any ideas why the URL "/HelloWorld" is not being found? Thanks.
Problem solved. I had to invoke the URL "/HelloWorld.htm" for the mapping to work.
(The Dispatcher-Servlet's mapping in web.xml is "*.htm".) Thanks
I'm trying to test a service with Mockito and testNG, but i have a couple of doubts. It's necessary create get/set to inject service, if service is declaredd like this:
#Autowired(required = true)
protected ITipService serveiTip;
when I'm trying to clean and package with maven I found this exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consultaDeutes' defined in URL
[file:/D:/workspaceGPT/GPT/gpt.ui/target/test-classes/applicationContext-gui-deutes-Test.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'serveiTip' of bean class [cat.base.gpt.ui.ConsultaDeutesTest]: Bean property 'serveiTip' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
I believe that with autowiring get/set will be not necessary.
this is my test-context:
?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:mockito="http://www.mockito.org/spring/mockito"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.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">
<context:annotation-config/>
<context:component-scan base-package="cat.base.gpt.ui" />
<!-- mock del serveis que podem atacar per solicitar info -->
<mockito:mock id="serveiSubjecte" class="cat.base.tip.service.ISubjectesService"/>
<mockito:mock id="serveiTip" class="cat.base.tip.service.ITipService"/>
<mockito:mock id="serveiGpt" class="cat.base.gpt.domini.service.IGptService"/>
<mockito:mock id="sessio" class="cat.base.baseframe.session.IBaseSession"/>
<mockito:mock id="usuari" class="cat.base.baseframe.user.IBaseUser"/>
<!--
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:cat/base/bfp/ui/applicationResources" />
</bean>
-->
<bean name="consultaDeutes" class="cat.base.gpt.ui.ConsultaDeutesTest">
<property name="serveiTip" ref="serveiTip"/>
<property name="serveiGpt" ref="serveiGpt"/>
</bean>
</beans>
ApplicationContext:
<?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:mockito="http://www.mockito.org/spring/mockito"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.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">
<context:annotation-config/>
<context:component-scan base-package="cat.base.gpt.ui" />
<!-- mock del serveis que podem atacar per solicitar info -->
<mockito:mock id="serveiSubjecte" class="cat.base.tip.service.ISubjectesService"/>
<mockito:mock id="serveiTip" class="cat.base.tip.service.ITipService"/>
<mockito:mock id="serveiGpt" class="cat.base.gpt.domini.service.IGptService"/>
<mockito:mock id="sessio" class="cat.base.baseframe.session.IBaseSession"/>
<mockito:mock id="usuari" class="cat.base.baseframe.user.IBaseUser"/>
<!--
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:cat/base/bfp/ui/applicationResources" />
</bean>
-->
<bean name="consultaDeutes" class="cat.base.gpt.ui.ConsultaDeutesTest"/>
<!-- WITH OUT PROPERTIES!!-->
</beans>
Using #Autowired will make spring automatically inject a matching bean into that field. Thus it is no longer required to define the "consultaDeutes" bean in the xml. If you'd like to use the xml definition, I believe you should define a setter for each property that you are trying to inject, eg: serveiTip, serveiGpt.
Using #Autowired in your test might require 2 additional annotation on the definition of your test class:
#ContextConfiguration(value = "/myContext.xml")
//#RunWith(SpringJUnit4ClassRunner.class) This is JUnit specific
#ActiveProfiles("dev")
public class TestCompareService {
#Autowired(required = true)
protected ITipService serveiTip;
....
}
I actually made a mistake pasting the #RunWith annotation specific for JUnit. For TestNG you can lookup this link. Apologies