[Seasar-user:21926] (Seasar2.4)ClassLoaderのduplicate class definitionエラーが発生するケースがあります
今田 昇
[E-MAIL ADDRESS DELETED]
2014年 7月 17日 (木) 19:28:29 JST
お世話になっております。
今田と申します。
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();
のように変更することで、エラーを回避できました。
対応方法に誤り、勘違い等があればご指摘ください。
以上、ご報告いたします。
-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: <http://ml.seasar.org/archives/seasar-user/attachments/20140717/e37c532a/attachment.html>
Seasar-user メーリングリストの案内