ClassLoader help!

Okay, so I’m making a plugin loader for my project, and this is essentially the code to it:

File folder = new File(System.getProperty("user.dir")+"/res/modules/");
		File files[] = folder.listFiles();

			for (int a = 0; a < files.length; a++){
				String classToUse = files[a].getName().replace(".class", "");
				
				ClassLoader loader = URLClassLoader.newInstance(
					    new URL[] { folder.toURL() }, getClass().getClassLoader());
				
					Class<?> clazz = Class.forName(classToUse, true, loader);
					Class<? extends Object> starter = clazz.asSubclass(Object.class);
					Constructor<? extends Object> constructor = 
						starter.getDeclaredConstructor(String[].class, String[].class, String.class);
					Object start = constructor.newInstance(sent, tags, sentence);
			}

It passes in some necessary variables the engine itself generates for the modder to work with but there is actually one very necessary object that needs to be passed through, and that is the Brain object. This gives them access to all of the programs information that’s stored in it, but I have no way of sending this seemingly.

Essentially, what I’m asking, is how would I import aida.neural.Brain into a class that is in the resources folder and not in any way connected to the rest and be able to call functions from it? I just need to it to call them blindly if so needed, just compile and do what it’s supposed to once loaded.

Please also know I’m a novice with ClassLoader, so don’t make fun of me too bad if this is easy, Hahah.

Instead of Constructor<? extends Object> use Constructor<? extends Plugin>.

Plugin has a method, setBrain(Brain b).

Cas :slight_smile:

Alright, I’ll give it a go, thank you.

Edit, it didn’t work!

Here’s the modified code:

File folder = new File(System.getProperty("user.dir")+"/res/modules/");
			File files[] = folder.listFiles();
	
				for (int a = 0; a < files.length; a++){
					String classToUse = files[a].getName().replace(".class", "");
					
					ClassLoader loader = URLClassLoader.newInstance(
						    new URL[] { folder.toURL() }, getClass().getClassLoader());
					
						Class<?> clazz = Class.forName(classToUse, true, loader);
						Class<? extends Brain> starter = clazz.asSubclass(Brain.class);
						Constructor<? extends Brain> constructor = 
							starter.getDeclaredConstructor(String[].class, String[].class, String.class, Brain.class);
						Object start = constructor.newInstance(sent, tags, sentence, Brain.get());
				}

Here’s the test plugin code:

public class ModuleTest {
	public ModuleTest(String[] sent, String[] tags, String sentence, Brain b){
		System.out.println(sentence +"/"+b.getName());
	}
}

I get the ClassCastException.

What do I do?

You are creating a new classloader every pass through the loop. Every Brain class you load through this new classloader is incompatible with any Brain class loaded through any other classloader – they’re completely different classes as far as Java’s concerned.

Is there a particular reason you’re creating a new classloader rather than using the existing loader of whatever class uses Brain?

Well, from my understanding, which isn’t much, I couldn’t load the plugin through the normal ClassLoader because that would mean it would have to be in the classpath, which is something I’d rather not force on the plugin makers. The plugins are in the resource folder.

putting your plugins on the classpath shouldn’t be that big of a problem.
You could use the classpath wildcards from Java 6:
java -cp libs/* resources/plugins/* -jar MyApp.jar

It’s the fact that people will have to open the Jar. Most average joes won’t want to do that crap, and the little Java you’ll need to know to make the plugins is all that I want to be necessary.

why should anybody have to open any jar? and which “average” joes are you talking about^^

Well generally the ClassPath is inside a jar after compilation. I may be wrong. Average Joes being the average people using this AI’s brain to make simple plugins to be more flexible for what they want it to do. If I can get the brain working outside, it’d be as a simple as this:

subject = brain.findSubject(sentence);

if (subject.related("Command here"){
do command}

Otherwise these will have to be done manually, which no one likes.

Can someone please give me some kind of Code example that would help with my problem? I’m a bit of a visual learner.