5

Mavenで構築されたAspectJ 1.6.12とSpring 3.1.2.RELEASEを使用するJBoss 6.1.0.Finalで問題なく動作する一連のWARがあります。近い将来、JBoss AS 7 に移行したいので、ソースから JBoss 7.1.3.Final をコンパイルしました。

個々の WAR ファイルで問題が発生したため、アプリケーションを EAR ファイルとして再パッケージ化することにしました。これにより、すべてのコードが 1 つの再配布可能でデプロイ可能なユニットになります。

プロファイリングの側面を機能させるのに問題があります。これは、EAR/lib ディレクトリの JAR に含まれる非常に単純な側面であり、@Timed アノテーションが付けられたすべてのメソッドの時間を計測します。

package com.mycompany.toplayer.perf;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


@Component
@Aspect
public class MethodTimerAdvice {
    private Logger log = LoggerFactory.getLogger(getClass());

    @SuppressWarnings("unchecked")
    @Around(value="execution(@com.mycompany.toplayer.perf.Timed * *(..))")
    public Object timeMethod(ProceedingJoinPoint pjp) throws Throwable
    {
        String methodName = pjp.getSignature().toShortString();
        long start = System.currentTimeMillis();

        Object ret = pjp.proceed();

        long end = System.currentTimeMillis();

        long total = end - start;

        long used_mem = Runtime.getRuntime().totalMemory()
                - Runtime.getRuntime().freeMemory();
        long mem_gb = used_mem / (1024 * 1024);     

        log.trace("{} | {} | {}M | {} | {} | {}", 
                new Object[] {start, total, 
                        mem_gb, 
                        Thread.currentThread().getId(), 
                        Thread.currentThread().getName(),   
                        methodName}
        );

        return ret;
    }
}

注釈は同じパッケージにあることに注意してください。
アスペクトに関連する Spring 構成ファイルは次のとおりです。これも非常に単純です。

<?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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        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.0.xsd">

    <context:component-scan base-package="com.mycompany" />
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

EAR には 3 つの WAR ファイルが含まれていますが、現在このアスペクトを使用しているのはそのうちの 1 つ、gdm-updater.WAR だけです。サーバーを起動しようとすると、次のようなエラーが発生します。

Caused by: java.lang.IllegalArgumentException: warning no match for this type name: Timed [Xlint:invalidAbsoluteTypeName]
    at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301) [aspectjtools.jar:]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:207) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getFallbackPointcutExpression(AspectJExpressionPointcut.java:358) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getShadowMatch(AspectJExpressionPointcut.java:409) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.matches(AspectJExpressionPointcut.java:272) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:226) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:264) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:296) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:117) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:87) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:68) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1598) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:162) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    ... 28 more

また、モジュールとして AspectJ を含めてみました。ここに、EAR に含まれる jboss-deployment-structure.xml ファイルがあります。

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
    <exclusions>
      <module name="org.hibernate" slot="main"/>
    </exclusions>
  </deployment>
  <sub-deployment name="gdm-updater-1.2.0-SNAPSHOT.war"> 
      <exclusions>
          <module name="org.hibernate" slot="main"/>
        </exclusions>
        <dependencies>
          <module name="org.aspectj.tools" slot="main" />
          <module name="org.aspectj.weaver" slot="main" />
        </dependencies>
  </sub-deployment>   
</jboss-deployment-structure>

gdm-updater.war で Maven AspectJ コンパイラ プラグインを使用して、gdm-updater.war の pom.xml でコンパイル時の織り込みを行ってみました。

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.4</version>
    <configuration>
        <showWeaveInfo>true</showWeaveInfo>
        <source>${compiler.version}</source>
        <target>${compiler.version}</target>
        <Xlint>ignore</Xlint>
        <complianceLevel>${compiler.version}</complianceLevel>
        <encoding>UTF-8</encoding>
        <verbose>false</verbose>
        <aspectLibraries>
            <aspectLibrary>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
            </aspectLibrary>
        </aspectLibraries>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
    </dependencies>
</plugin>   

何も機能しません。Web で回答を検索したところ、いくつかのリンクが見つかりましたが、関連するものはないようです。

JBoss AS 7.1.1 final で AspectJ を実行した人はいますか? -ロードタイムウィービングを使用していないため、関係ありません

https://issues.jboss.org/browse/AS7-3681 - ロードタイム ウィービングまたは AspectJ を Java エージェントとして使用していないため関係ありません

読み込み時の織り込みを検討しましたが、問題の側面はすぐに拡張されて、その「共通」jar ファイルの残りの部分に存在するいくつかの機能が含まれるようになり、それをブート クラスパスに分割することはできません。これは、新しい側面があるたびに、サーバーを再構成する必要があることを意味します。

私は何を間違っていますか?

4

4 に答える 4

7

私にとって、これはほとんどの場合「うまくいく」。JBossAS7でロードタイムウィービングを使用せずに単純な側面をテストしているサンプル プロジェクトがあります。

私にとってうまくいかない部分は、私が次のようなオブジェクトを指定した場合です:

<jee:jndi-lookup id="dataSource" jndi-name="jboss/datasources/ExampleDS"/>

これには問題があります。これは、JBoss内部モジュールがその特定のモジュールに対してのみ可視性を持つModuleClassLoaderでロードされるためです。ただし、Aspect-Jはそのアスペクトをチェックしようとして失敗します。これは、その特定のクラスローダーにアスペクトクラスがロードされていないためです。ここで説明したのと同じです。

回避策は、module.xml/jboss-deployment-structure.xmlのjdbc内部に依存することです。

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
  <dependencies>
    <module name="org.jboss.ironjacamar.jdbcadapters"/>
  </dependencies>
</deployment>
</jboss-deployment-structure>

デバッガーを使用する場合は、例外java.lang.IllegalArgumentExceptionをフックして、使用しているクラスローダーと、呼び出しスタックからロードしようとしているクラスを確認できます。それが私がしたことです。

私が見つけたもう1つの回避策は、Springコンテキストではなく、コードで直接JNDIルックアップを実行することでした。それもうまくいきます。

この問題については、AS7-6305/WFLY-826も開いています。

更新:JBoss側で問題が拒否されました。彼らはそれがAspectJの問題だと主張している。そこにもバグを開いており、コメントはありません。

于 2013-01-10T08:49:04.260 に答える
1

ここで少なくとも部分的な解決策を見つけました...

http://pushpendrasinghbaghel.blogspot.com/2013/01/spring-aop-and-jbossas-7.html

この問題は、コア JBoss モジュールをロードするクラスローダーによってロードされる何かを通知する必要があるときにいつでも発生するようです...

于 2013-05-31T23:17:53.313 に答える
0

私も同じ問題を抱えていました。spring-aop ライブラリのバージョンを 3.0.7.RELEASE にダウングレードすることで解決しました。もちろん、これは一時的な解決策であり、この問題の真の理由を待っています。

于 2013-01-16T15:10:37.110 に答える