有一个著名的trick与URLClassLoader
。通过使用它,我们可以让jsch
访问ant-jsch
。
我不知道如何从@ user3499805答案classloadertask
的作品。
<target name="injectJsch" description="inject jsch jar">
<makeurl file="${acdc.java.tools}/lib/jsch-0.1.50.jar" property="jsch.jar.url"/>
<taskdef name="injectJsch"
classname="tools.deployments.ant.InjectJsch"
classpath="${basedir}/jars/ajwf_deploytools.jar"
/>
<injectJsch jarLocation="${jsch.jar.url}"/>
</target>
_
package tools.deployments.ant;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.optional.ssh.LogListener;
public class InjectJsch extends Task {
public void setJarLocation(final String jarLocation) {
this.jarLocation = jarLocation;
}
@Override
public void execute() throws BuildException {
try {
injectJsch(new URL(jarLocation));
} catch (final Exception e) {
throw new BuildException(e);
}
}
public static void injectJsch(final URL jarLocation) throws Exception {
ClassLoader parent = LogListener.class.getClassLoader();
try {
parent.loadClass(TESTCLASS);
} catch (final ClassNotFoundException e) {
final Method addURLmethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addURLmethod.setAccessible(true);
ClassLoader cl;
do {
cl = parent;
if (cl instanceof URLClassLoader) {
addURLmethod.invoke(cl, jarLocation);
break;
}
parent = cl.getParent();
} while (parent != cl && parent != null);
LogListener.class.getClassLoader().loadClass(TESTCLASS);
}
}
private String jarLocation;
private static final String TESTCLASS = "com.jcraft.jsch.UserInfo";
}
看来这是一个普遍的问题,我觉得这是最好的解决办法,除了没有失败,我要先走一步,删除/ lib中/蚂蚁-jsch.jar。如果它帮助其他人,Paulo在他的SO中解释了核心问题[回答相关的SCP问题](http://stackoverflow.com/questions/5796587/problems-with-ant-optional-tasks-sshexec-和-scp-classpath-issue)和[同样的问题出现在junit中,并在这里解释](http://ant.apache.org/faq.html#delegating-classloader) – gMale 2011-08-12 14:29:29
但是这需要修改标准的Ant安装。 – 2016-08-04 08:07:10
我一直在努力解决这个问题几天,这个解决方案是我唯一能够工作的解决方案! – 2017-08-23 14:14:08