Answer the question
In order to leave comments, you need to log in
Classloader and what does it represent?
Good day. The essence of the following is the interface
public interface Module {
public int run();
}
Answer the question
In order to leave comments, you need to log in
The topic with class loading is already quite hackneyed and the theory on it is easy to google. In a couple of minutes I found
the official docks ,
a rather detailed article from someone's blog ,
a recording of a speech at the JUG.RU conference Let
's decide
on the initial conditions. As I understand it, there is a folder with jar files. You need to go through all the jar files and get a list of classes that implement Module
. Something like
Let's assume that 1 jar file can contain only one module (hereinafter, "module" is a class that implements the interfaceModule
). Here is the most non-trivial question, how to find this module inside the archive. The easiest (for starters) way is to put a config in each jar file in a certain path, in which you specify the path to the module. And there is already such a config in the jar file - standard META-INF. In the simplest case, we get a jar file from two files with the following structure:
MyMod.jar
├───META-INF
│ └───MANIFEST.MF
└───mymod
└───MyMod.class
MANIFEST.MF
contains the string Module
. Contents of MyMod.javapackage mymod;
public class MyMod implements Module {
public int run() {
System.out.println("MyMod loaded!");
}
}
public class ModuleLoader {
public static void main(String[] args) {
List<Module> mods = new ModuleLoader().discoverModules(new File("/modules"));
for(Module mod : mods)
mod.run();
}
public List<Module> discoverModules(File dir) {
List<File> jarFiles = Stream.of(dir.listFiles())
.filter(f -> f.getName().endsWith(".jar"))
.collect(Collectors.toList());
URL[] moduleUrls = jarFiles.stream().map(this::toUrl).toArray(URL[]::new);
URLClassLoader classLoader = new URLClassLoader(moduleUrls, getClass().getClassLoader());
return jarFiles.stream()
.map(this::getMainClassName)
.map(name -> {
try {
return (Module) classLoader.loadClass(name).newInstance();
} catch(Exception e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
}
private String getMainClassName(File file) {
try(JarFile jar = new JarFile(file)){
return (String) jar.getManifest().getMainAttributes().get("Main-Class");
} catch(IOException e) {
throw new RuntimeException(e);
}
}
private URL toUrl(File file) {
try {
return file.toURI().toURL();
} catch(MalformedURLException e) {
throw new RuntimeException(e);
}
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question