[Seasar-user:21930] Re: (Seasar2.4)ClassLoaderのduplicate class definitionエラーが発生するケースがあります

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2014年 8月 10日 (日) 21:43:11 JST


小林 (koichik) です。

遅くなりましたが、修正しました。

https://github.com/seasarorg/seasar2/pull/6

SNAPSHOTをデプロイしました (修正はs2-frameworkのみ)。

http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-framework/2.4.48-SNAPSHOT/s2-framework-2.4.48-20140810.123506-2.jar
http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-extension/2.4.48-SNAPSHOT/s2-extension-2.4.48-20140810.123506-2.jar
http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2-tiger/2.4.48-SNAPSHOT/s2-tiger-2.4.48-20140810.123827-2.jar
http://maven.seasar.org/maven2-snapshot/org/seasar/container/s2jdbc-gen/2.4.48-SNAPSHOT/s2jdbc-gen-2.4.48-20140810.123912-2.jar


On Mon, 28 Jul 2014 03:15:36 +0900, Koichi Kobayashi <koichik @ improvement.jp> wrote:

> 小林 (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 mailing list
> Seasar-user @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/seasar-user


-- 
{
  name: "Koichi Kobayashi",
  mail: "koichik @ improvement.jp",
  blog: "http://d.hatena.ne.jp/koichik/",
  twitter: "@koichik"
}



Seasar-user メーリングリストの案内