2017-05-07 45 views
1

我正在做一個任務來創建一個Java應用程序。任務是在不重新編譯應用程序的情況下更改方法(計算公式)。在谷歌搜索後,我意識到你可以在javassist的幫助下解決問題。到目前爲止,我正在嘗試一個簡單的例子。 所以,包含我想改變Javassist,java

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

的唯一方法和類的類從我改變方法

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; 
} 

開始我得到的輸出

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 

後幫瞭解如何修正這個錯誤

回答

0

你的錯誤是在這一行:

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

首先,您已經創建了池,因此應該將類路徑插入到該池中。其次,類路徑應該是代碼所在類的類名。

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

查看documentation。在Class search path

+0

的部分太感謝你了!但現在還有第二個問題 - 當你重新查詢錯誤ru.testScandJavaCafee.service.Helper類被凍結,如果我添加cc.defrost(),它給出了一個錯誤javassist.CannotCompileException:由java.lang.LinkageError的:loader(org/apache/catalina/loader/WebappClassLoader的實例):試圖爲名稱重複的類定義:「ru/testScandJavaCafee/service/Helper」 \t at javassist.ClassPool.toClass(ClassPool.java:1085) \t at javassist.ClassPool.toClass(ClassPool.java:1028) \t在javassist.ClassPool.toClass(ClassPool.java:986) –

+0

什麼叫 「重新查詢錯誤」 是什麼意思? – tima

+0

重新啓動該方法會導致錯誤 –