Заменяя классы из JARs ранее в Classpath - PullRequest
2 голосов
/ 13 декабря 2010

Я раздаю некоторый код моим студентам-программистам первого семестра, которые создают ZIP-архив своих домашних заданий в Eclipse.Для назначения N я создаю метод main в классе hwN.Submitter, который вызывает метод библиотеки foo.Submit.zip ().Я распространяю основную и библиотеку в исполняемом JAR.foo довольно стабильный, но иногда он меняется.Библиотека входит в JAR-файл каждого домашнего задания.

Теперь предположим, что учащийся добавляет JAR-файл hw1 в путь сборки Eclipse.Затем я изменяю API foo.Submit для hw2 и распространяю его JAR.Поскольку он был добавлен позже в путь сборки, hw2.Submitter завершает загрузку foo.Submit из JAR hw1, который не содержит метод с момента изменения API.

Теперь у меня есть несколько вариантов:A) попросите моих учеников удалить старые JAR-файлы, B) попросите моих учеников изменить порядок пути сборки, или C) напишите мой собственный загрузчик классов.Мне не нравится А, потому что им полезно запускать JAR на старых домашних заданиях.Я не люблю B, потому что они программисты первого семестра.И я не могу заставить работать C.

Я поиграл с URLClassLoader, но загрузчик родительского класса сначала находит классы в старых JAR.Как я могу заменить эти старые JAR-файлы или переопределить загрузчик родительского класса?

1 Ответ

2 голосов
/ 13 декабря 2010

Ладно, потыкаюсь еще немного, я смог найти решение.Это загрузчик классов, который я придумал:

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;
  }
}

Снимаю шляпу перед Алекс Миллер для рабочего примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...