我想创建一个可以在我项目的JSF页面中使用的实体转换器。
我的项目结构如下:
- project-ear.ear
| --- project1-ejb.jar
| --- project2-web.war
| --- lib
| --- | --- warframework.jar
| --- | --- ekbframework.jar
在lib.jar中,我有一个absctract类EntityConverter
在lib/warframework.jar
中实现了JSF转换器逻辑。
public abstract class EntityConverter implements Converter {
protected abstract EntityLoader getEntityLoader();
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (StringUtils.isBlank(value)) return null;
try {
String[] split = value.split(":");
return getEntityLoader().loadEntity(split[0], Long.valueOf(split[1]));
} catch (NumberFormatException e) {
return null;
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) return null;
if (value instanceof AbstractEntity) {
return value.getClass() + ":" + ((AbstractEntity) value).getSid();
} else {
return value.toString();
}
}
}
EntityLoader
中的界面lib/ejbframework.jar
。
public interface EntityLoader {
AbstractEntity loadEntity(String className, Long sid);
}
我正在使用Mavens WAR-Overlay功能将不同的war文件合并为一个。我有一个project1-web.war
,其中包含project2-web.war
。
在project1-web.war
中我定义了Converter的具体实现:
@Named
@FacesConverter("concreteEntityConverter")
public class ConcreteEntityConverter extends EntityConverter {
@Inject
private ConcreteEntityLoader entityLoader;
@Override
protected EntityLoader getEntityLoader() {
return entityLoader;
}
}
在project1-ejb.jar中,我定义了EntityLoader
实现:
public class ShsEntityLoader implements EntityLoader {
@Inject
Logger log;
@Inject
protected EntityManager entityManager;
@Override
public AbstractEntity loadEntity(String className, Long sid) {
AbstractEntity entity = null;
try {
entity = (AbstractEntity) entityManager.find(Class.forName(className), sid);
} catch (ClassNotFoundException ex) {
log.warn("Could not load entity for class: " + className, ex);
}
return entity;
}
}
部署ear
并触发转换器后,出现以下错误:
无法为类加载实体:class de.example.com.user.model.MyEntity:java.lang.ClassNotFoundException:来自[Module“deployment.project-ear的class de.example.com.user.model.MyEntity .ear.project1-ejb.jar:main“来自服务模块加载器”
在org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198)
在org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
在org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
在org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
at java.lang.Class.forName0(Native Method)
在java.lang.Class.forName(Class.java:264)
at de.example.com.common.service.ConcreteEntityLoader.loadEntity(ConcreteEntityLoader.java:30)
类de.example.com.user.model.MyEntity
与EntityLoader
一样存在于同一个jar中。我认为,会发生此异常,因为实体转换器是从project2-web.war
文件调用的,该类加载器无法访问project1-ejb.jar
中的类。它是否正确?我需要更改什么才能正确加载类?
答案 0 :(得分:0)
发现问题:
EntityConverter.getAsString()
中的代码会创建对象的错误字符串表示形式:
return value.getClass() + ":" + ((AbstractEntity) value).getSid();
结果是:class de.example.com.user.model.MyEntity:1
而不是预期de.example.com.user.model.MyEntity:1
。
将上面的代码更改为以下内容,可使所有内容按预期工作:
return value.getClass().getCanonicalName() + ":" + ((AbstractEntity) value).getSid();