[Seasar-user:21929] Re: (Seasar2.4)ClassLoaderのduplicate class definitionエラーが発生するケースがあります
Koichi Kobayashi
[E-MAIL ADDRESS DELETED]
2014年 7月 28日 (月) 03:15:36 JST
小林 (koichik) です。
返事が遅くなって申し訳ありません。
> メソッド名 + “$$” + 連番
確かにそうすべきですね。
近いうちに修正します (プルリク歓迎です)。
On Thu, 17 Jul 2014 10:28:29 +0000, 今田 昇 <n-imada @ sakura-is.co.jp> wrote:
> お世話になっております。
> 今田と申します。
>
> Seasar2を便利に利用させていただいております。
> いつもありがとうございます。
>
> さて、
> Seasar2.4において
> (試したのは2.4.46)
> ClassLoaderのduplicate class definitionエラーが発生するケースがあります。
>
> 発生条件は以下のとおりです。
>
> コンポーネント
> 例:root.service.sample.Test2Service.java
> に、
> 以下のようなpublicメソッドを定義します。
>
> package root.service.sample;
>
> public class Test2Service {
>
> //0
> public void testA1() {
> }
> //1
> public void testB1() {
> }
> //2
> public void testC1() {
> }
> //3
> public void testD1() {
> }
> //4
> public void testE1() {
> }
> //5
> public void testF1() {
> }
> //6
> public void testG1() {
> }
> //7
> public void testH1() {
> }
> //8
> public void testI1() {
> }
> //9
> public void testJ1() {
> }
>
> //10
> public void testA() {
> }
>
> }
>
> そして、
> customizer.diconに、
> <component name="serviceCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain">
> <initMethod name="addCustomizer">
> <arg>traceCustomizer</arg>
> </initMethod>
> </component>
>
> のように、
> コンポーネントのメソッドに対してAOPを設定して、
> スマートデプロイすると、
>
> 各メソッドに対して割り当てられるAOPのクラス名は、
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testA10
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testB11
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testC12
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testD13
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testE14
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testF15
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testG16
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testH17
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testI18
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testJ19
>
> root.service.sample.Test2Service$$EnhancedByS2AOP$$149b290$$MethodInvocation$$testA10
>
> のようになるので、
>
> testA1 + 0
> と
> testA + 10
>
> の部分でクラス名が重複してしまうのです。
>
> メソッドが処理される順番は、
> org.seasar.framework.aop.proxy.AopProxy.javaの
> setupAspectsメソッドにて、
>
> targetClass.getMethods()
>
> にて取得される順番となります。
>
> java.lang.ClassのgetMethods()メソッドは、
> Method[]の配列が返されますが、
> メソッドの順序はなんら保証されないため、
> 必ずしも、上記の順番にはならないのですが、
> 上記の順番にたまたまなってしまった場合には、
> クラス名が重複して、
> ClassLoaderの
> duplicate class definitionエラーが発生してしまいます。
>
> クラス名に連番を振っているのは、
> 同一メソッド名でのオーバーロードがあった場合の処置だと思いますが、
> 上記のケースがあるので、
>
> 最後のメソッド名 + 連番
> の部分を
> メソッド名 + “$$” + 連番
> のようにする必要があると思います。
> ($$じゃなくても良いですが・・・)
>
> 具体的には、
> org.seasar.framework.aop.javassist.AspectWeaver.java
> の
> getMethodInvocationClassNameメソッドを
>
> return enhancedClassName + SUFFIX_METHOD_INVOCATION_CLASS
> + method.getName() + "$$" + methodInvocationClassList.size();
>
> のように変更することで、エラーを回避できました。
>
> 対応方法に誤り、勘違い等があればご指摘ください。
>
> 以上、ご報告いたします。
>
--
{
name: "Koichi Kobayashi",
mail: "koichik @ improvement.jp",
blog: "http://d.hatena.ne.jp/koichik/",
twitter: "@koichik"
}
Seasar-user メーリングリストの案内