AspectJ 加载时间 Weaving 在部署的 EAR 中无法正常工作 类
AspectJ load time Weaving not working properly within EAR deployed classes
我正在处理一个由许多 WAR 文件组成的多模块项目。这些项目使用 Spring 4.0.5 来管理依赖项,并使用 AspectJ 1.8.5 和加载时间编织来支持 AOP(Spring 基本 AOP 支持在这个项目中还不够)。另外,META-INF目录下有一个aop.xml,配置很简单:
<aspectj>
<aspects>
<!--No need to specify any aspect here-->
</aspects>
<weaver options="-XnoInline -verbose">
<include within="com.myproject..*" />
</weaver>
</aspectj>
AOP 主要用于提供各种服务和DAO(用@Service 和@Repository 标注),具有Transactional 行为(用spring 的@Transactional 标注)。例如:
@Service(value = "alertService")
public class AlertServiceImpl implements IAlertService, Serializable {
...
@Transactional(rollbackFor = Exception.class)
@Override
public Alert createAlert(Alert alert) {
alertDAO.create(alert);
return alert;
}
...
}
或者应用程序的其余 DAO 继承的抽象 Base DAO
@Repository
public abstract class BaseDAO<E extends IBusinessObject, PK extends Serializable> {
...
@Transactional(readOnly = true)
public <C extends E> C findFirstByFields(Class<C> type, String[] fields, Object[] values, String[] dependencies)
throws ModelException {
List<C> list = findAllByFields(type, fields, values, null, null, 1, null);
if (list.isEmpty()) {
return null;
} else {
C obj = list.get(0);
loadDependencies(obj, dependencies);
return obj;
}
}
...
}
最终项目使用 maven 构建并在 JBoss EAP 6.1 上运行。
因此,使用此配置,在构建和部署 WAR 文件时一切正常。但是,如果我仅使用其中一个 WAR 文件构建一个简单的 EAR 文件,则加载时间编织会编织除一个 BaseDAO 之外的所有类。
我已经为此苦苦挣扎了很多时间,我唯一能得到的是在应用程序启动时,编织在两种情况下几乎相同,除了在 EAR 中,BaseDAO 没有编织。我不知道为什么。知道为什么会这样吗?
P.D.: 从 WAR:
启动应用程序时,启用 AspectJ 编织日志会显示此信息
...
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure3'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure5'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.services.Repository$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure3'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure5'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure7'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.model.dao.LastDocumentNumberDAO$AjcClosure1'
...
但是当用这个 war 启动 EAR 时,BaseDAO class 被完全忽略:
...
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure3'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure5'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.services.Repository$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.model.dao.LastDocumentNumberDAO$AjcClosure1'
...
终于找到问题所在了。它在 jboss-deployment-structure.xml 中。
项目中的每个 war 都有自己的 jboss-部署-structure.xml,但有一些例外:
<jboss-deployment-structure>
<deployment>
<!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->
<exclusions>
<module name="org.apache.log4j" />
<module name="org.slf4j" />
<module name="org.apache.commons.logging" />
<module name="org.log4j" />
<module name="org.jboss.logging" />
<module name="org.javassist" />
<module name="org.hibernate.validator" />
<module name="org.jboss.ws.cxf" />
</exclusions>
<exclude-subsystems>
<subsystem name="webservices" />
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
但是在 EAR 部署中,EAR 的特定 jboss-deployment-structure.xml 丢失了,所以类加载器以非常不同的方式工作,造成了我 post 在我的问题。只需将 jboss-deployment-structure.xml(EAR 部署,即 WAR 的组合)放入 EAR 的 META-INF 中即可解决问题。
希望这对遇到类似问题的人有所帮助。
我正在处理一个由许多 WAR 文件组成的多模块项目。这些项目使用 Spring 4.0.5 来管理依赖项,并使用 AspectJ 1.8.5 和加载时间编织来支持 AOP(Spring 基本 AOP 支持在这个项目中还不够)。另外,META-INF目录下有一个aop.xml,配置很简单:
<aspectj>
<aspects>
<!--No need to specify any aspect here-->
</aspects>
<weaver options="-XnoInline -verbose">
<include within="com.myproject..*" />
</weaver>
</aspectj>
AOP 主要用于提供各种服务和DAO(用@Service 和@Repository 标注),具有Transactional 行为(用spring 的@Transactional 标注)。例如:
@Service(value = "alertService")
public class AlertServiceImpl implements IAlertService, Serializable {
...
@Transactional(rollbackFor = Exception.class)
@Override
public Alert createAlert(Alert alert) {
alertDAO.create(alert);
return alert;
}
...
}
或者应用程序的其余 DAO 继承的抽象 Base DAO
@Repository
public abstract class BaseDAO<E extends IBusinessObject, PK extends Serializable> {
...
@Transactional(readOnly = true)
public <C extends E> C findFirstByFields(Class<C> type, String[] fields, Object[] values, String[] dependencies)
throws ModelException {
List<C> list = findAllByFields(type, fields, values, null, null, 1, null);
if (list.isEmpty()) {
return null;
} else {
C obj = list.get(0);
loadDependencies(obj, dependencies);
return obj;
}
}
...
}
最终项目使用 maven 构建并在 JBoss EAP 6.1 上运行。
因此,使用此配置,在构建和部署 WAR 文件时一切正常。但是,如果我仅使用其中一个 WAR 文件构建一个简单的 EAR 文件,则加载时间编织会编织除一个 BaseDAO 之外的所有类。
我已经为此苦苦挣扎了很多时间,我唯一能得到的是在应用程序启动时,编织在两种情况下几乎相同,除了在 EAR 中,BaseDAO 没有编织。我不知道为什么。知道为什么会这样吗?
P.D.: 从 WAR:
启动应用程序时,启用 AspectJ 编织日志会显示此信息 ...
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure3'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure5'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.services.Repository$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure3'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure5'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure7'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.model.dao.LastDocumentNumberDAO$AjcClosure1'
...
但是当用这个 war 启动 EAR 时,BaseDAO class 被完全忽略:
...
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure3'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure5'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.services.Repository$AjcClosure1'
ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.model.dao.LastDocumentNumberDAO$AjcClosure1'
...
终于找到问题所在了。它在 jboss-deployment-structure.xml 中。 项目中的每个 war 都有自己的 jboss-部署-structure.xml,但有一些例外:
<jboss-deployment-structure>
<deployment>
<!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->
<exclusions>
<module name="org.apache.log4j" />
<module name="org.slf4j" />
<module name="org.apache.commons.logging" />
<module name="org.log4j" />
<module name="org.jboss.logging" />
<module name="org.javassist" />
<module name="org.hibernate.validator" />
<module name="org.jboss.ws.cxf" />
</exclusions>
<exclude-subsystems>
<subsystem name="webservices" />
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
但是在 EAR 部署中,EAR 的特定 jboss-deployment-structure.xml 丢失了,所以类加载器以非常不同的方式工作,造成了我 post 在我的问题。只需将 jboss-deployment-structure.xml(EAR 部署,即 WAR 的组合)放入 EAR 的 META-INF 中即可解决问题。
希望这对遇到类似问题的人有所帮助。