JavaOp appears to load plugin JARs in to the CP; if that's how it works, how's it done?
I want to be able to load JDBC drivers on-the-fly.
It's opensource, have a look!
I seem to remember using Class.forName(), though. The Class class (ha!) has what you need, I think.
Class.forName(..) just returns a <Class>; its purpose is to verify that a class is in the classpath, and to kick off any static initializers. That particular method will not add new JARs to the classpath.
I'll have a look at the rest of Class's methods, though.
[edit] Nevermind, you were right, iago. There are two forNames(); I didn't realize there was one that took a ClassLoader.
http://www.kfu.com/~nsayer/Java/dyn-jdbc.html
URL u = new URL("jar:file:/path/to/pgjdbc2.jar!/");
String classname = "org.postgresql.Driver";
URLClassLoader ucl = new URLClassLoader(new URL[] { u });
Driver d = (Driver)Class.forName(classname, true, ucl).newInstance();
DriverManager.registerDriver(new DriverShim(d));
DriverManager.getConnection("jdbc:postgresql://host/db", "user", "pw");
Got it working. I wrote a class that provides a new forName(String), and will load any class out of any jar in the lib folder.
http://bnubot.googlecode.com/svn/trunk/BNUBot/src/net/bnubot/JARLoader.java
I'm a bit rusty. The return from that method should be cast to match an Interface, correct?
I assume you're referring to JARLoader.forName(String)? Since it's a simple redirect to URLClassLoader.loadClass(String), you could consult the documentation for that method, but I'll take a stab at it anyways, even though I'm not sure I understand your question entirely.
The return value of the method is Class<?>, which is the standard way of specifying unknown origin in Java 1.5+ -- it's functionally equivalent to saying Class<Object>, but is more specific. With a Class object, you can induce reflection upon the class, create an instance according to the constructor "new ?()", and do a number of other things.
Why would you want to cast a Class<?> to an interface? It does implement a few things (Serializable, and three reflection-specific things), but the reduction is fruitless.
Can you access methods in the Class<?> just by calling them? The reason I thought you'd have to have to cast it to an interface is because the Loader doesn't know the loaded class' methods at compile-time.
If you use reflection, you can invoke a method (or constructor) without knowing the class structure at compile time (although it helps to avoid invocation exceptions). The javadoc on reflection is pretty good, you should read it. I think I have an old topic in here somewhere about the performance differences associated with reflection as well (Myndfyre even made some pretty graphs ;))
Quote from: Joex86] link=topic=10210.msg129802#msg129802 date=1189443013]
Can you access methods in the Class<?> just by calling them? The reason I thought you'd have to have to cast it to an interface is because the Loader doesn't know the loaded class' methods at compile-time.
The method returns an object of type Class<?>.
Class is defined like so:
public class Class<T> {
public T newInstance() throws ...;
}
Actually, if you look at the real definition, that's not how it works (it always returns an Object), but it's guaranteed to either return one of whatever the class was, or throw an exception. Therefore, it's safe to cast to what you were expecting without type-checking. Just be aware you could get a cast exception if you create something that you weren't expecting.
Driver d = (Driver)JARLoader.forName(driver).newInstance();
DriverManager.registerDriver(new DriverShim(d));