2011-09-17 67 views
0

我有一个“com.test.Test1”类,它在test.jar中。我使用这个jar进行编译,但没有使用我的webapp进行部署。我希望我的servlet在运行时动态加载这个jar。Thread.currentThread()。setContextClassLoader不使用反射

有什么方法可以在不使用Java反射的情况下动态加载类?我之所以问这个问题是因为我不想将大量现有代码转换为java反射。

public class servlet1 extends HttpServlet { 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException { 

     URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { new File("test.jar").toURI().toURL() }, null); 
     Thread.currentThread().setContextClassLoader(urlClassLoader); 
     Class c = newClassLoader.loadClass("com.test.Test1"); 

     ////// 
     Test1 test1 = new Test1() ==> ClassNotFound Exception 
     test1.testMeothod(); 
     ///////  

     // if using java reflection will work 
     c.newInstance() ........... 
     Method m = c.getDeclaredMethod("startup", null); 
     ..... 
     ..... 
     //////  
    } 
} 

回答

1

您可以加载类这种方式,但你不能他们的代码。你必须通过它们扩展/实现的classpainter来引用它们。如果类具有默认构造函数,则不必使用Reflection,只需Class.newInstance()

+0

我建议避免'Class.newInstance',因为它是邪恶的。推出船并罚款'构造函数'。 –

+0

@Tom。你有什么建议的细节?想要了解它。 –

+0

@Clark Ba​​o用'Class.getConstructor'获取'Constructor'。用'Constructor.newInstance'调用。这可以防止任何检查的异常直接通过未经检查。 –

0

你可以重构你的代码来拉出Test1的接口。 所以你可以直接使用你的界面而不用反射。 接口被推荐,由于使用抽象类会导致 在其他类加载器中加载子类时出现一些麻烦。

你可以在这里找到麻烦。

ClassCircularityError is thrown when getCanonicalName

+0

抽象基类必须由加载使用类的类加载器加载,例如, OP公布的代码。您的链接不适用。 – EJP

+0

对不起,我不明白。我的意思是最好的做法是使用接口作为存根。 –