Суть проблемыНеобходимо в мультимодульном Maven проекте добавить несколько методов к сервису и потом использовать эти методы вызывая их из контроллера MVC.
Сначала приведу небольшой обзор проекта, т.к. потом легче объяснить в чем проблема.
Maven-проект состоящий из следующих основных модулей:
- map-tool // mvc
- app-ear // типа как пакет для app-ejb
- app-ejb // сервис
- app-model // orm модель
- ...
Вот интерфейс сервиса:
[app-ejb\src\main\java\com\rootdata\app\ejb\facade\portlet\userbase\IAppUserBaseService.java]
| Код |
package com.rootdata.app.ejb.facade.portlet.userbase; import java.util.List; import com.rootdata.app.ejb.facade.IAppEao; import com.rootdata.app.model.dto.*; public interface IAppUserBaseService extends IAppEao { public static final String JNDIName = "ejb/AppUserBase"; // ... List<User> getUsers() throws Exception; // метод который уже изначально был User getUserByKey(String key) throws Exception; // метод который нужно мне добавить, что я и делаю } |
Далее переходим к реализации этого интерфейса:
[app-ejb\src\main\java\com\rootdata\app\ejb\db\portlet\userbase\AppUserBaseBean.java]
| Код |
package com.rootdata.app.ejb.db.portlet.userbase;
import javax.ejb.EJB; import javax.ejb.Remote; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import java.math.BigDecimal; import java.math.BigInteger; import java.util.LinkedList; import java.util.List;
import com.rootdata.app.ejb.facade.*; import com.rootdata.app.ejb.facade.portlet.userbase.IAppUserBaseService ; import com.rootdata.app.model.dto.*; import com.rootdata.app.model.entity.*; import com.rootdata.app.model.util.EntityToDTOUtil;
@Stateless(name = IAppUserBaseService .JNDIName) @Remote(IAppUserBaseService .class) public class AppUserBaseBean implements IAppUserBaseService { ... @EJB IUserEao userEao; ... @PersistenceContext(unitName = PERSISTENT_CTX_UNIT_NAME) private EntityManager em; ... @Override public List<User> getUsers() throws Exception { // изначально было List<com.rootdata.app.model.entity.User> userEntities = userEao.getUsers(); return (List<User>) EntityToDTOUtil.copyBeanListProperties(User.class, new LinkedList<User>(), userEntities); } @Override public Branch getUserByKey(String key) throws Exception { // метод, который я добавил для своей задачи com.rootdata.app.model.entity.User user = userEao.findByKey(key); return (User) EntityToDTOUtil.copyProperties(new User(), user); } }
|
В реализации используется EAO, ниже показан интерфейс и реализация:
[app-ejb\src\main\java\com\rootdata\app\ejb\facade\IUserEao.java]
| Код |
package com.rootdata.app.ejb.facade;
import java.util.List;
import com.rootdata.app.model.entity.User;
public interface IUserEao extends IAppEao { public static final String JNDIName = "ejb/AppUser"; ... List<User> getUsers(); // было User findByKey(String key) throws Exception; // я добавил } |
[app-ejb\src\main\java\com\rootdata\app\ejb\db\UserEao.java]
| Код |
package com.rootdata.app.ejb.db;
import javax.ejb.Remote; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import java.util.LinkedList; import java.util.List;
import com.rootdata.app.ejb.facade.IUserEao; import com.rootdata.app.model.entity.User; import com.rootdata.app.model.util.EntityToDTOUtil;
@Stateless(name = IUserEao.JNDIName) @Remote(IUserEao.class) public class UserEao implements IUserEao { @PersistenceContext(unitName = PERSISTENT_CTX_UNIT_NAME) private EntityManager em; @Override public List<User> getUsers() { // было javax.persistence.Query query = em.createQuery("from User u where u.blocked = false "); return query.getResultList(); } ... @Override public User findByKey(String key) throws Exception { // я добавил javax.persistence.Query query = em.createQuery("from User u where u.key = :key ").setParameter("key", key); return (User) query.getSingleResult(); } } |
Теперь контроллер. Он находится в другом модуле.
[map-tool\src\main\java\com\rootdata\app\portlet\map-tool\spring\controller\UserController.java]
| Код |
package com.rootdata.app.portlet.map_tool.spring.controller;
import javax.portlet.PortletRequest; import javax.portlet.PortletSession; import java.util.List; import java.util.ResourceBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.portlet.bind.annotation.ResourceMapping;
import com.rootdata.app.ejb.facade.portlet.userbase.IAppUserBaseService; import com.rootdata.app.model.dto.User;
@RequestMapping(value = "VIEW") @Controller(value = "mapToolController") public class UserController { @ResourceMapping("USER") public String list(@RequestParam(value = "mapToolStatus", required = false) String mapToolStatus, Model model, PortletRequest request) throws Exception { ... usersAll = userService.getUsers(); // этот метод работает всегда userSingle = userService.getBranchByKey(key); // это метод который добавил я. есть условия при которых он не работает. подробнее далее... ... return "user/list"; } } |
Также в этом модуле находится конфиг Spring.
[map-tool\src\main\webapp\WEB-INF\app_map-tool-portlet.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:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans [url]http://www.springframework.org/schema/beans/spring-beans-3.0.xsd[/url] [url]http://www.springframework.org/schema/context[/url] [url]http://www.springframework.org/schema/context/spring-context-3.0.xsd[/url] [url]http://www.springframework.org/schema/jee[/url] http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"> <context:component-scan base-package="com.rootdata.app.portlet.map_tool.spring.controller"/> ... <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/> ... <jee:jndi-lookup id="userService" jndi-name="app-ear-1.0/ejb/AppUserBase/remote" proxy-interface="com.rootdata.app.ejb.facade.portlet.userbase.IAppUserBaseService" lookup-on-startup="false"> <jee:environment> java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=jnp://localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces </jee:environment> </jee:jndi-lookup> </beans> |
Теперь в чем проблема. Разработку я веду в IntelliJ IDEA 11.
Как вы видели я просто добавил еще один метод для своей задачи и прописал его использование в другом модуле.
1) Если делать compile и package в целом для всего проекта, то на выходе получаем app-ear.ear и map-tool.ear и др. пакеты, которые успешно деплоятся и работают.
app-ear.ear
map-tool.ear 2) Однако, дальше если я внесу изменения в map-tool и сделаю его компиляцию, package и деплоймент
app-ear.ear // оставляю прежний потому что ничего в нем не менял
map-tool.ear // заменяю на новый измененныйто при работе с ним буду получать ошибку на всех вызовах
своего (подчерквиваю т.к. другие методы которые изначально были работают) добавленного метода:
| Код |
usersAll = userService.getUsers(); // здесь не будет ошибки userSingle = userService.getBranchByKey(key); // это метод который добавил я. здесь будет ошибка!!!
|
САМА ОШИБКА:
| Код |
15:13:22,400 ERROR [DispatcherPortlet] Could not complete request javax.portlet.PortletException: Error occured during request processing: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at org.springframework.web.portlet.DispatcherPortlet.doResourceService(DispatcherPortlet.java:872) ... at java.lang.Thread.comn(Thread.java:662) Caused by: java.lang.NoSuchMethodError: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at com.rootdata.app.portlet.map_tool.spring.controller.UserController.list(UserController.java:41) ... 197 more 15:13:22,930 ERROR [DispatcherPortlet] Could not complete request javax.portlet.PortletException: Error occured during request processing: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at org.springframework.web.portlet.DispatcherPortlet.doResourceService(DispatcherPortlet.java:872) ... at java.lang.Thread.comn(Thread.java:662) Caused by: java.lang.NoSuchMethodError: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at com.rootdata.app.portlet.map_tool.spring.controller.UserController.list(UserController.java:41) ... 197 more 15:13:23,607 ERROR [org_springframework_web_portlet_DispatcherPortlet] The portlet threw an exception javax.portlet.PortletException: Error occured during request processing: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at org.springframework.web.portlet.DispatcherPortlet.doResourceService(DispatcherPortlet.java:872) ... at java.lang.Thread.comn(Thread.java:662) Caused by: java.lang.NoSuchMethodError: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at com.rootdata.app.portlet.map_tool.spring.controller.UserController.list(UserController.java:41) ... 197 more 15:13:24,313 ERROR [DefaultPortalControlPolicy] Rendering portlet window produced an error javax.portlet.PortletException: Error occured during request processing: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at org.springframework.web.portlet.DispatcherPortlet.doResourceService(DispatcherPortlet.java:872) ... at java.lang.Thread.comn(Thread.java:662) Caused by: java.lang.NoSuchMethodError: com.rootdata.app.ejb.facade.portlet.user.IAppUserBaseService .getBranchByKey(Ljava/lang/String;)Lcom/rootdata/app/model/dto/User; at com.rootdata.app.portlet.map_tool.spring.controller.UserController.list(UserController.java:41) ... 197 more |
Почему вызов моего метода в этой ситуации дает ошибку?
Это сообщение отредактировал(а) Mindzor - 4.8.2012, 02:51