0

Notice

Marked as a duplicate? I could definitely be wrong, but I’m not capable of seeing as to why the duplicate question would help. We’ve already established some sort of progress due to previous comments—comments that clearly have showed solutions that I’ve actually needed rather than marking it as a duplicate for some utterly useless information.

Creating object from class located inside JAR?

I’m currently attempting to create a system for managing .jar plugins from inside another Java project. The idea is that it should be able to create an object out of a class always named Plugin located inside another .jar file, and then load then initialize that class like you would any other Java class.

Progress

I’ve managed to locate the .jar I wish to load classes from using a File from the java.io package. I messed around with the JarFile for a short while, but realized I wasn’t going to be able to achieve what I’m after using it. Always fun playing around with something new!

Research

Over the period of time I’ve been sitting with this, I’ve found several posts here on Stackoverflow, that neither one can be used in order to achieve what I’m after:

It would seem to me as though it’s not an easy task. Any thoughts on these two resources would be highly appreciated should they prove to be of any use for my problem.

Moreover

It is a .jar file I’d like to load a class into an object from, whilst the application loading the class is up and running—in order for the user to be able to add more plugins, restart and enjoy!

Perhaps someone could point me in the right direction?

Example

Someone suggested I attach an example of what I’m currently attempting—that someone was also nice enough to link me to one of their answers to another question.

Here’s what I’ve tried using that approach:

// ...
// The ‘folderPlugins’ is a file set to the folder containing all plugins
File plugin = new File(folderPlugins.getPath() + "/" + jar);

URLClassLoader classLoader = null;

// First try / catch block used to instantiate the `URLClassLoader` works like a charm
try
{
    classLoader = new URLClassLoader(new URL[] {plugin.toURI().toURL()});
}
catch (MalformedURLException ex)
{
    System.out.println("0");

    Logger.getLogger(Plugins.class.getName())
            .log(Level.SEVERE, null, ex);

    System.exit(0);
}

Class cls = null;

// Second try / catch block used to load up the class also works like a charm!      
try
{
    cls = classLoader.loadClass("x.X");

    // This nicely outputs into the console as the loaded class ‘class x.X’
    System.out.println("Cls: " + cls);
}
catch (ClassNotFoundException ex)
{
    System.out.println("1");

    Logger.getLogger(Plugins.class.getName())
            .log(Level.SEVERE, null, ex);

    System.exit(0);
}

// This is where ‘hell breaks lose’.        
try
{
    // Rather than ending up in here, the ‘catch’ block is used
    Object object = cls.newInstance();
}
catch (InstantiationException | IllegalAccessException ex)
{
    // Console prints ‘2’
    System.out.println("2");

    Logger.getLogger(Plugins.class.getName())
            .log(Level.SEVERE, null, ex);

    System.exit(0);
}
// ...

Part of the error generated by the last try / catch block is the following:

...
java.lang.InstantiationException: textarea.TextArea
...
Caused by: java.lang.NoSuchMethodException: textarea.TextArea.<init>()    at
java.lang.Class.getConstructor0(Class.java:3082)  at
java.lang.Class.newInstance(Class.java:412)
...

This error corresponds to the same line as the only one inside the last try block—that’s where the error occurs.

Community
  • 1
  • 1
D. Ataro
  • 1,711
  • 17
  • 38
  • 1
    If you are fine with "restart and enjoy" you can just add that jar to the application's classpath (for example by copying it into a directory that gets included). Then the normal classloader can pick it up. – Thilo Jan 15 '17 at 23:48
  • Sounds unnecessarily complex to me. An easier solution would be to externalize those classes as a JAR and add them to the other project as a dependency using Maven. You're over complicating this. – duffymo Jan 15 '17 at 23:48
  • I would need users to be able to easily add any plugins they require into a plugins folder—the plugins nicely loading into the program upon a restart to begin with, dynamically loading them I’m pretty sure I’ll be able to figure out on my own. – D. Ataro Jan 15 '17 at 23:49
  • 1
    https://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html – Marvin Jan 15 '17 at 23:53
  • 1
    I'd start by having a look at [`URLClassloader`](https://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html), which will allow to load the jar and generate class/object instances – MadProgrammer Jan 15 '17 at 23:53
  • [For example](http://stackoverflow.com/questions/28470081/how-to-load-my-jar-to-classpath-at-runtime-through-java-coding/28470194#28470194) – MadProgrammer Jan 15 '17 at 23:59
  • @MadProgrammer I followed your answer from the post you provided me with, but it’s giving me a `java.lang.InstantiationException: textarea.TextArea` upon doing `cls.newInstance()`, the class loader successfully loads the class from inside the `.jar`. – D. Ataro Jan 16 '17 at 00:20
  • 2
    @D.Ataro Without out some kind of runnable example, it's going to be impossible to help you much further. It sounds to me that the `TextArea` relies on something else which is causing it to fail when it's been instantiated, it should include the "cause" as part of the exception – MadProgrammer Jan 16 '17 at 00:21
  • @MadProgrammer I added an example and commented it out the best I could. – D. Ataro Jan 16 '17 at 00:33
  • 2
    it is telling you that that class does not have a `no args constructor`. Research what `java.lang.NoSuchMethodException init` means. Very common error that is very well documented if you search for this simple string. –  Jan 16 '17 at 00:56
  • Everything works fine. The loaded class just do not definde a default constructor. – xry Jan 16 '17 at 01:13

0 Answers0