Problem with loading java plugins packaged into jar, contained resources
I have problem with design of my application. I have main application (let's call it as App) which is based on plugins. Everthing is written in Java. PLugins are dynamically loaded during App startup. During plugins loading App search specific loaction ("/plugins" directory) and then load plugins, which are pacaked into jar files.
The problem is following: When plugin (packaged into jar) contains functionality, which is coded in *class files - everthing is OK. But when Plugin class uses any resources (eg. text file, image) - there is a problem, because during running this plugin in main application (App) I get the exception:
java.io.FileNotFoundException: sampletxt (Nie można odnaleźć określonego pliku)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at java.io.FileInputStream.<init>(FileInputStream.java:79)
at java.io.FileReader.<init>(FileReader.java:41)
I know why this problem occurs, but I dont have idea how to cope with this issue. Resource, which is used by plugin class is always present in jar file. But problem is caused by loading only plugin class in main application (App) - I don't load resource (sampletxt), because I don't know anything about resources that can be used by plugins class.
To clarify this situation: Main App have something like this:
class App {
public void any method() {
Class<PluginDataGenerator> plugin = jarClassLoader.loadClass("mypackage.plugin."+className, true);
PluginDataGenerator plg = plugin.newInstance();
plg.doAction();
}
}
So in this code I load plugin with given name (className). Now, Plugin class may have something like this code:
class Plugin {
public void doAction() {
try {
BufferedReader reader = new BufferedReader(new FileReader(
"sampletxt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And now when doAction method is invoked I get java.io.FileNotFou开发者_JAVA技巧ndException. One solution that I have thought about is to create folder "resources" in App directory structure and to place there any resources that plugin classes could use. But this is not good solution because in this situation Plugin (packaged into jar) would be distributed independently from its resource. Another idea that I think is to place any entry into Manifest file in jar. This entry could inform plugin loader which resource should load moreover. But from this point of view when plugin code:
BufferedReader reader = new BufferedReader(new FileReader(
"sampletxt"));
is executed App willl search "sampletext" in main directory of App, not in memory, so in this case should I copy resource from jar and paste it into specific dir in App? It seems bad solution as well.
I don't have idea how to design my App and plugins. Any ideas will be appreciated.
Try using Class.getResource or Class.getResourceAsStream instead.
E.g.
BufferedReader reader = new BufferedReader(
new InputStreamReader(Plugin.class.getResourceAsStream("sampletxt")));
Where Plugin
is the name of your plugin class.
I just ran into a problem similar to this. In your plugin, I would call:
File f = FileLocator.toFileUrl(getClass().getResource("/sampletext.txt")).getFile();
精彩评论