Может ли каталог быть добавлен к пути classа во время выполнения?
Чтобы лучше понять, как все работает на Java, я хотел бы знать, могу ли я динамически добавлять во время выполнения каталог в путь к classу.
Например, если я запустил .jar, используя «java -jar mycp.jar» и вывел свойство java.class.path , я могу получить:
java.class.path: '.:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java'
Теперь я могу изменить этот путь classа во время выполнения, чтобы добавить другой каталог? (например, перед первым вызовом classа с использованием .jar, который находится в этом каталоге, который я хочу добавить).
- Java-ориентированное программирование с аннотациями
- Как правильно использовать ClassLoader.getResources ()?
- Синглтон с аргументами в Java
- Java Swing: зачем изменять размер frameworks, чтобы добавить компоненты, добавленные
- Как удалить одиночный символ из строки
- Как сравнивать CDI и EJB? взаимодействовать?
- Java: если A расширяет B и B расширяет Object, то это множественное наследование
- Как Thread может вернуть значение после завершения работы?
- Форматирование Log4j: возможно ли обрезать стопку стеков?
- Как работает аннотация «Spring @ResponseBody» в этом примере приложения RESTful?
- Измените размер изображения в соответствии с JLabel
- Почему Java не предлагает перегрузку оператора?
- Как избежать «ConcurrentModificationException» при удалении элементов из «ArrayList» при его повторении?
Вы можете использовать следующий метод:
URLClassLoader.addURL(URL url)
Но вам нужно будет сделать это с reflectionм, поскольку метод protected
:
public static void addPath(String s) throws Exception { File f = new File(s); URL u = f.toURL(); URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class urlClass = URLClassLoader.class; Method method = urlClass.getDeclaredMethod("addURL", new Class[]{URL.class}); method.setAccessible(true); method.invoke(urlClassLoader, new Object[]{u}); }
См. Java Trail on Reflection . Особенно в разделе « Недостатки отражения»
Обновление 2014: это код из принятого ответа Джонатана Спунера с 2011 года, слегка переписанный, чтобы валидаторы Eclipse больше не создавали предупреждений (debrecation, rawtypes)
//need to do add path to Classpath with reflection since the URLClassLoader.addURL(URL url) method is protected: public static void addPath(String s) throws Exception { File f = new File(s); URI u = f.toURI(); URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class urlClass = URLClassLoader.class; Method method = urlClass.getDeclaredMethod("addURL", new Class[]{URL.class}); method.setAccessible(true); method.invoke(urlClassLoader, new Object[]{u.toURL()}); }
Да, вы можете использовать URLClassLoader
.. см. Пример здесь . Не использует reflection.
— редактировать —
Копирование примера из ссылки, как было предложено.
import javax.naming.*; import java.util.Hashtable; import java.net.URLClassLoader; import java.net.URL; import java.net.MalformedURLException; public class ChangeLoader { public static void main(String[] args) throws MalformedURLException { if (args.length != 1) { System.err.println("usage: java ChangeLoader codebase_url"); System.exit(-1); } String url = args[0]; ClassLoader prevCl = Thread.currentThread().getContextClassLoader(); // Create class loader using given codebase // Use prevCl as parent to maintain current visibility ClassLoader urlCl = URLClassLoader.newInstance(new URL[]{new URL(url)}, prevCl); try { // Save class loader so that we can restore later Thread.currentThread().setContextClassLoader(urlCl); // Expect that environment properties are in // application resource file found at "url" Context ctx = new InitialContext(); System.out.println(ctx.lookup("tutorial/report.txt")); // Close context when no longer needed ctx.close(); } catch (NamingException e) { e.printStackTrace(); } finally { // Restore Thread.currentThread().setContextClassLoader(prevCl); } } }