Описание проблемы: скомпилировать 2 файла jar независимо, без необходимости включать друг друга в путь к классам; и во время выполнения включите оба и вызовите main () в одном jar, чтобы напечатать строку на stdout. Части выходной строки должны быть из второго баночка.
Ограничения: Решение не может зависеть от IDE или использовать любые другие файлы JAR.
Ответ на вопрос, что я сделал до сих пор: Мое решение описано ниже.
Причина задать вопрос: я пытаюсь выяснить, если / как использовать аннотации для решения этой проблемы (надеюсь, более элегантным способом), но не могу найти какую-либо подходящую документацию или учебное пособие. Я также ценю любые указатели для этого.
Мое решение: Пакетный файл (в Unix измените обратную косую черту на прямую косую черту, точку с запятой на двоеточие и значения rem на #) следующим образом:
rem Compile and package the testing class (Main) without any library
javac -d target core\*.java
cd target
jar cvf ..\main.jar .\core
cd ..
rem Compile and package the Greeting and Greeted classes as a library
javac -d lib impl\*.java
cd lib
jar cvf ..\mylib.jar .\impl
cd ..
rem Use the two parts above at runtime and execute main() in Main class
java -cp main.jar;mylib.jar core.Main
В каталоге impl есть 2 файла и 2 в ядре, как указано ниже:
/ * Файл: impl / Greeting.java * /
package impl;
public class Greeting {
public String getGreeting () {
return "Hello";
}}
/ * Файл: impl / Greeted.java * /
package impl;
public class Greeted {
public String getGreeted () {
return "world";
}
/ * Файл: core / Main.java * /
package core;
public class Main {
private String greeting = "Learn annotations", greeted = "keep using Java",
// Can read the following 4 values from a configuration file, too
// Trying to see if we can get these using Java annotations
greetingClassName = "impl.Greeting", greetingMethod = "getGreeting",
greetedClassName = "impl.Greeted", greetedMethod = "getGreeted";
public Main () {
try {
MyRunTime runTime = new MyRunTime();
Object gting = runTime.getInstance(greetingClassName),
gted = runTime.getInstance(greetedClassName),
g1Str = runTime.getResponseNoArg (gting, greetingMethod),
g2Str = runTime.getResponseNoArg (gted, greetedMethod);
if (g1Str instanceof String) greeting = (String) g1Str;
if (g2Str instanceof String) greeted = (String) g2Str;
} catch (Exception ex) {
System.err.println ("Error in Library loading: " + ex.getMessage());
}}
public void greet () {
System.out.println (greeting + ", " + greeted + "!");
}
public static void main (String[] args) {
new Main().greet();
}}
/ * Файл: core / MyRunTime.java * /
package core;
import java.lang.reflect.*;
public class MyRunTime {
public Object getResponseNoArg (Object anInstance, String methodName) throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
Method method = anInstance.getClass().getMethod (methodName);
return method.invoke (anInstance);
}
public Object getInstance (String className) throws
ClassNotFoundException,
InstantiationException,
IllegalAccessException {
Class c = Class.forName (className);
return c.newInstance();
}
}
Вот и все. Я также хотел бы не связываться с ClassLoader, если это абсолютно необходимо. Как только я получу информацию о том, как сделать это с помощью аннотаций, я могу рассмотреть передаваемые аргументы и идти вперед. Спасибо за вашу помощь.