在Classpath中早期从JAR中取代类

时间:2010-12-13 03:41:45

标签: java eclipse

我将一些代码分发给我的第一学期编程学生,他们在Eclipse中创建了他们的家庭作业的ZIP存档。对于赋值N,我在类hwN.Submitter中创建一个main方法,它调用库方法foo.Submit.zip()。我将main和库分发到可执行的JAR中。 foo相当稳定,但偶尔会发生变化。该库捆绑在每个作业的JAR文件中。

现在,假设学生将hw1的JAR添加到Eclipse的Build Path中。然后我为hw2更改了foo.Submit的API并分发了它的JAR。由于它稍后在构建路径中添加,因此hw2.Submitter最终从hw1的JAR加载foo.Submit,因为API已更改,所以它不包含该方法。

现在,我似乎有几个选择:A)告诉我的学生删除旧的JAR,B)告诉我的学生重新排序构建路径,或者C)编写我自己的类加载器。我不喜欢A,因为它们对旧作业中运行JAR很有用。我不喜欢B,因为他们是第一学期的程序员。我不能让C工作。

我玩过URLClassLoader,但是父类加载器首先在旧JAR中查找类。我怎样才能取代这些旧的JAR或覆盖父类加载器?

1 个答案:

答案 0 :(得分:2)

好的,再多一点,我找到了解决方案。这是我提出的类加载器:

package speccheck;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * Create a class loader which favors speccheck.* classes from the JAR
 * associated with the homework.
 */
public class LatestSpecCheckClassLoader extends URLClassLoader {
  /**
   * Create a loader which checks $(pwd)/bin/speccheck_TAG_DO_NOT_SUBMIT.jar
   * first for speccheck.* classes
   * 
   * @param tag
   * Homework tag, like "hw4" or "pre2".
   * @throws MalformedURLException
   */
  public LatestSpecCheckClassLoader(String tag) throws MalformedURLException {
    super(new URL[]{new URL("file://" + System.getProperty("user.dir") + "/bin/" + tag + "/speccheck_" + tag + "_DO_NOT_SUBMIT.jar")});
  }

  @Override
  public Class<?> loadClass(String name) throws ClassNotFoundException {
    // Check for cached.
    Class<?> loadedClass = findLoadedClass(name);
    if (loadedClass != null) {
      return loadedClass;
    }

    // If the class is in the speccheck package, do not delegate to parent
    // loader. Check in the URLs registered with this loader instead.
    try {
      if (name.startsWith("speccheck.")) {
        loadedClass = findClass(name);
      }
    } catch (ClassNotFoundException e) {
    }

    // If still not found, then let's defer.
    if (loadedClass == null) {
      return super.loadClass(name);
    }

    return loadedClass;
  }
}

Alex Miller作为工作示例。