В основном вы хотите реализовать extensibility или плагин шаблон проектирования. Существует несколько способов реализации этого сценария.
Какой бы компонент вы ни выбрали, чтобы разрешить кому-либо перезагрузить модуль, определить интерфейс и реализовать свою собственную реализацию как стандартную.Например, здесь я пытаюсь представить HelloInterface, которые каждая страна может осуществлять и загружать в любое время,
public interface HelloInterface {
public String sayHello(String input);
..
}
public class HelloImplDefault implements HelloInterface {
public String sayHello(String input) {
return "Hello World";
}
}
Теперь позволяют пользователю добавлять плагин (пользовательскую реализацию) файлы на предварительно сконфигурированные пути. Вы можете использовать файл FileSystemWatcher или фоновый поток для сканирования этого пути и попытаться скомпилировать и загрузить файл.
Для компиляции Java-файл,
private void compile(List<File> files) throws IOException{
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromFiles(files);
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null,
null, compilationUnits);
boolean success = task.call();
fileManager.close();
}
Чтобы загрузить файл класса,
private void load(List<File> files) throws MalformedURLException, InstantiationException, IllegalAccessException, ClassNotFoundException{
ClassLoader cl = Thread.currentThread().getContextClassLoader();
for(File f: files){
if(f.getName().endsWith(".class") && !loadedClass.contains(f.getName())){
URL url = f.toURL();
URL[] urls = new URL[]{url};
Object obj = cl.loadClass(f.getName().replace(".class", "")).newInstance();
if(obj instanceof HelloInterface){
HelloProviders.addProvider((HelloInterface)obj);
System.out.println("Loaded "+ ((HelloInterface)obj).getProviderName());
}else{
//Add more classes if you want
}
loadedClass.add(f.getName());
}
}
}
На данный момент вы можете прочитать пользовательскую реализацию и загруженным в классе системы заряжания. Теперь вы готовы к работе. Для этого подхода есть последствия для безопасности, которые вам нужно изучать в Интернете.
Я реализовал один образец кода и опубликовал его в github, please take a look. Счастливое кодирование!
http://www.beanshell.org/manual/embeddedmode.html –
Интересно, что никто не упоминал OSGi. http://en.wikipedia.org/wiki/OSGi – Yser