[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 メーリングリストの案内