Tomcat 6 在加载类时首先在 .../WEB-INF/classes 中查找,然后在 .../WEB-INF/lib 中查找。我想在此搜索路径中添加另一个目录。此目录只能由特定的 web 应用程序使用。我想使用上下文 XML 文件配置它(我在想 Loader http://tomcat.apache.org/tomcat-6.0-doc/config/loader.html组件)
我读过这个
http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html
但它似乎没有给我答案。看着这个
http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/loader/WebappLoader.html
似乎我可以调用 addRepository 来添加一个新的 jar 文件或包含类的目录。但我不确定我会在哪里或如何称呼它。
目前我正在使用 bat 文件来启动我的 jar 并设置 java.system.class.loader。是否可以以编程方式执行此操作以摆脱 bat 文件?
我有一组 Groovy 文件,我使用 Groovy 的类加载器将它们解析为类:
GroovyClassLoader gcl = new GroovyClassLoader();
while (groovyIter.hasNext()) {
File groovyFile = (File) groovyIter.next();
try {
Class clazz = gcl.parseClass(groovyFile);
} catch (IOException ioe) {
log.error("Unable to read file " + groovyFile + " to parse class ", ioe);
}
}
Run Code Online (Sandbox Code Playgroud)
GroovyClassLoader 完成后,我使用 XStream 解析 XML 文件,将 XML 反序列化为 Groovy 对象的不同实例。我现在从一种类型开始:发票。为了让 XStream 可以看到 groovy 类,我将类加载器设置为 GroovyClassLoader 的实例。
XStream xstream = new XStream();
xstream.setClassLoader(gcl);
// Read the file and get objects
Object deserialized = xstream.fromXML(file);
Run Code Online (Sandbox Code Playgroud)
获得反序列化对象后,我想使用 …
抱歉,也许这个问题太愚蠢或已经回答了,但我找不到。
我想知道是否有一些已知的 Java 类加载器能够接受类路径中的远程文件,即像 CLASSPATH="http://somewhere.net/library.jar:..." 这样的条目。
请注意,我不是在谈论小程序或 Java Web Start。考虑一个可以使用不同后端(例如 MySQL、Oracle)的应用程序,我想根据用户的后端偏好在 shell 脚本中准备类路径,并让类加载器下载所需的jar(本例中的 jdbc 驱动程序)来自分发服务器。我也不是在谈论 Maven(用户只是获得二进制分发版,我不想强迫他们从源代码构建他们需要的东西)。
对于向后兼容性测试,我正在创建我自己的类加载器来加载我以前版本的一些代码。在我拥有自定义对象(来自较旧的自定义类)之后,我将使用反射调用它的 API。但是,当此类 API 方法具有自定义参数(不是 java 库的一部分)时,例如:
public void MyMethod(MyObj a) {}
Run Code Online (Sandbox Code Playgroud)
当我使用反射调用此方法时,我得到:
java.lang.IllegalArgumentException:参数类型不匹配
因为我从默认类加载器传递 MyObj 而该方法期望从自定义类加载器获取 MyObj。
我用来调用该方法的代码(而代理是由我的自定义类加载器加载的,代理的 api 方法的参数来自我的测试类,该类由默认类加载器加载)
private Object invoke(Object... args) {
try {
final String methodName = getMethodName();
final Class<?>[] methodArgs = getMethodArgs(methodName);
return agent.getClass().getMethod(methodName, methodArgs).invoke(agent, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
private Class<?>[] getMethodArgs(String methodName) {
final Method[] declaredMethods = agent.getClass().getDeclaredMethods();
for (Method method : declaredMethods) {
if …Run Code Online (Sandbox Code Playgroud) 我的构建脚本遇到错误(如下)。有没有办法使用与调用 Java 相同类型的输出来运行 Gradle -verbose:class?
有问题的错误,如果有人有一些输入:
Caused by: org.gradle.api.artifacts.ResolveException: Could not resolve all dependencies for configuration ':Project:compile'.
at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver.wrapException(ErrorHandlingArtifactDependencyResolver.java:49)
... more
Caused by: java.lang.LinkageError: loader constraints violated when linking org/apache/ivy/core/module/descriptor/DependencyDescriptor class
Run Code Online (Sandbox Code Playgroud) 意图:
我正在使用java.lang.instrument包为 Java 程序创建一些工具。这个想法是我通过这个系统使用字节码操作,以便在每个方法的开头和结尾添加方法调用。一般来说,经过修改的 Java 方法如下所示:
public void whateverMethod(){
MyFancyProfiler.methodEntered("whateverMethod");
//the rest of the method as usual...
MyFancyProfiler.methodExited("whateverMethod");
}
Run Code Online (Sandbox Code Playgroud)
MyFancyProfiler是一个相对复杂的系统的入口点,该系统在premain方法(它是 的一部分java.lang.instrument)期间被初始化。
编辑-MyFancyProfiler包含一个静态 API,它将通过类似于此问题的解决方案中描述的机制获取对系统其余部分的引用。引用作为 获取Object,并通过反射进行适当的调用,因此即使当前 ClassLoader 不知道底层类,它仍然可以工作。
困难
对于一个简单的 Java 程序,该方法工作正常。对于“真实”应用程序(如窗口应用程序,尤其是RCP/OSGi应用程序),我遇到了ClassLoaders. 有些ClassLoaders人不知道如何找到MyFancyProfiler该类,因此当它尝试调用MyFancyProfiler.
我至该溶液(并在我的真正的问题是发生)目前是“注入”MyFancyProfiler到每一个遇到ClassLoader的反射调用defineClass。它的要点是:
public byte[] transform(ClassLoader loader, String className, /* etc... */) {
if(/* this is the first time I've …Run Code Online (Sandbox Code Playgroud) 我正在使用大量静态方法对 SDK 进行单元测试。而且我不希望我在 test1() 中所做的操作影响我在 test2() 中所做的操作。在每次测试开始时,我需要 SDK 中的所有静态变量返回到未初始化状态,就好像它们没有加载一样。然后再次加载它们。关于如何做到这一点的任何建议?Robolectric 中是否有类似的规定?因为我用它来进行单元测试。在计划英语中,我基本上想要的是在每次测试开始时都有一个干净的石板。
@Test
public void test1() throws Exception {
// Setup all the device info values
MyDeviceInfoClass.setDeviceModel().equals("Nexus 4");
MyDeviceInfoClass.setDeviceOperatingSystem().equals("Android_3.4b5");
// Verify all the device info values set previously
assertTrue(MyDeviceInfoClass.getDeviceModel().equals("Nexus 4"));
assertTrue(MyDeviceInfoClass.getDeviceOperatingSystem().equals("Android_3.4b5"));
}
Run Code Online (Sandbox Code Playgroud)
那是第一次测试,它成功了。就是它应该的样子。然后在第二个测试中:
@Test
public void test2() throws Exception {
// Setup all the device info values
MyDeviceInfoClass.setDeviceOperatingSystem().equals("Android_4.2");
//The following line also succeeds if test1() is finished. But I do not want that. This line should throw an assertion error because we …Run Code Online (Sandbox Code Playgroud) defineClass(className, byte[], offset, length)。new CustomClassLoader(Thread.currentThread().getContextClassLoader())。因此,CustomClassLoader的父级是当前线程中的ClassLoader。Thread.currentThread().setContextClassLoader()用CustomClassLoader 设置了。Class.forName(String, true, the CustomClassLoader)。我怎么了?如果您需要更多信息,请在我的GitHub上找到详细的主题。
lihaoyi test$ tree
.
??? Foo.scala
0 directories, 1 file
lihaoyi test$ cat Foo.scala
object Main{
def main(args: Array[String]): Unit = {
println(getClass.getClassLoader.getResourceAsStream("java/lang/String.class"))
println(getClass.getClassLoader.getClass)
println(Thread.currentThread().getContextClassLoader.getResourceAsStream("java/lang/String.class"))
println(Thread.currentThread().getContextClassLoader.getClass)
}
}
lihaoyi test$ sbt run
[info] Loading global plugins from /Users/lihaoyi/.sbt/0.13/plugins
[info] Set current project to test (in build file:/Users/lihaoyi/Dropbox/Workspace/test/)
[info] Updating {file:/Users/lihaoyi/Dropbox/Workspace/test/}test...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/lihaoyi/Dropbox/Workspace/test/target/scala-2.10/classes...
[info] Running Main
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@18e38ff2
class sbt.classpath.ClasspathUtilities$$anon$1
null
class sbt.classpath.ClasspathFilter
[success] Total time: 2 s, completed 29 …Run Code Online (Sandbox Code Playgroud) classloader ×10
java ×7
android ×1
classpath ×1
gradle ×1
groovy ×1
hibernate ×1
junit ×1
jvm ×1
jvmti ×1
osgi ×1
reflection ×1
remoteobject ×1
robolectric ×1
sbt ×1
scala ×1
superclass ×1
tomcat ×1
tomcat6 ×1