2017-05-07 9 views
1

私は、Javaアプリケーションを作成する作業をしています。タスクは、アプリケーションを再コンパイルせずにメソッド(計算式)を変更することです。 Googleで検索した後、あなたはjavassistの助けを借りて問題を解決できることに気付きました。これまで私は単純な例を試しています。だから、 、私はJavassist、java

package ru.testScandJavaCafee.service; 
public class Helper { 
public String createList() 
{ 
    System.out.println("++++"); 
    return "1000"; 
} 
} 

そして私は、私は、出力

javassist.CannotCompileException: by java.lang.LinkageError: loader (instance of org/apache/catalina/loader/WebappClassLoader): attempted duplicate class definition for name: "ru/testScandJavaCafee/service/Helper2" 
    at javassist.ClassPool.toClass(ClassPool.java:1085) 
    at javassist.ClassPool.toClass(ClassPool.java:1028) 
    at javassist.ClassPool.toClass(ClassPool.java:986) 
    at javassist.CtClass.toClass(CtClass.java:1110) 
    at ru.testScandJavaCafee.controller.CoffeeTypeController.createMethodHelper(CoffeeTypeController.java:111) 
    at ru.testScandJavaCafee.controller.CoffeeTypeController.doPost(CoffeeTypeController.java:56) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:452) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.LinkageError: loader (instance of org/apache/catalina/loader/WebappClassLoader): attempted duplicate class definition for name: "ru/testScandJavaCafee/service/Helper2" 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at javassist.ClassPool.toClass2(ClassPool.java:1098) 
    at javassist.ClassPool.toClass(ClassPool.java:1079) 
    ... 27 more 

ヘルプを起動した後方法

package ru.testScandJavaCafee.controller; 

import javassist.*; 
import ru.testScandJavaCafee.service.Helper; 

import java.io.IOException; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 


/** 
* Created by 15 on 06.05.2017. 
*/ 

public class CoffeeTypeController { 

public String createMethodHelper() throws NotFoundException, CannotCompileException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, InstantiationException, ClassNotFoundException { 

    ClassPool pool = ClassPool.getDefault(); 
    ClassPool.getDefault().insertClassPath(new ClassClassPath(ru.testScandJavaCafee.service.Helper2.class)); 

    CtClass cc = pool.get("ru.testScandJavaCafee.service.Helper"); 

    CtMethod cm = cc.getMethod("createList","()Ljava/lang/String;"); 

    cm.setBody("{ return \"200 \" ;}"); 
    cc.toClass(); 

    Helper helper = new Helper(); 
    Method method1 = helper.getClass().getMethod("createList"); 
    String sum = (String)method1.invoke(helper); 
    return sum; 
} 

を変更する元のクラスを変更したいだけの方法を含むクラスエラーを修正する方法を理解する

答えて

0

あなたはエラーがこの行にあります:

ClassPool.getDefault().insertClassPath(new ClassClassPath(ru.testScandJavaCafee.service.Helper2.class)); 

まず、すでにプールを作成しているため、そのプールにクラスパスを挿入する必要があります。次に、クラスパスは、コードが存在するクラスのクラス名とみなされます。

pool.insertClassPath(new ClassClassPath(this.getClass())); 

documentationを参照してください。セクションはClass search path

+0

ありがとうございました!しかし、今度は2番目の問題があります。 - ru.testScandJavaCafee.service.Helperクラスのエラーを再クエリするとcc.defrost()を追加すると、エラーが発生します。javassist.CannotCompileException:java.lang.LinkageError :ローダー(ORG/apacheの/カタリナ/ローダ/ WebappClassLoaderのインスタンス):名前の重複クラス定義を試みた: "RU/testScandJavaCafee /サービス/ヘルパー" \t javassist.ClassPool.toClass(ClassPool.java:1085)で \tでjavassist.ClassPool.toClass(ClassPool.java:986) –

+0

「エラーを再クエリする」とはどういう意味ですか? – tima

+0

メソッドを再起動するとエラーが発生する –

関連する問題