Re: [classloading] How to use URLClassLoader within a servlet
Okay, I moved the JAR to $CATALINA_HOME/webapps/ROOT and changed the code to: Great, and thanks. In about two hours I will stop the daunting task of creating a web application in VBScript/ASP (yuck) and picking up the registry-system again. I will immediately try out your way. I suspect the magic is using the context class loader. I will try it out and let you know. Yours grateful /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
[classloading] How to use URLClassLoader within a servlet
I have this problem with using my own (URLClassLoader) class loader in a servlet of mine. The thing is that I am writing a web front end to domain name services (automatic registration of .org, .com. .biz, .info etc domains). Depending on the top level domain, I need to use different versions (jars) of the same API, since the protocol differs. So I need to dynamically load my classes at runtime. Just putting the jars in lib won't work since there are different implementations of the same classes in them. I have to decide in runtime. Using the URLClassLoader in a standalone app works perfectly, when using it in a servlet it just hangs. I suspect the problem lies within the different lookup order used in servlets (as dscribed in the classloader-HOWTO). I can't figure out how to do it. Has anyone experience in the field? /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: [classloading] How to use URLClassLoader within a servlet
I would recommend to use a different approach: Define an interface for the API. Implement the different protocols in different classes with unique names. Load the classes dynamically and store instances of the classes in variables. Use the interface to access the api. public class DomainFactory { Hashtable cTldClassNames = new Hashtable(); static { cTldClassNames.put(BIZ, package.BizProtocol); cTldClassNames.put(INFO, package.InfoProtocol); } static IProtocol getInstance(String aTld) { return Class.forName(getTldClassName(aTld)).newInstance(); } static String getTldClassName(String aTld) { return (String) cTldClassNames.get(aTld.toUpperCase()); } } public class BizProtocol implemets IProtocol { } IProtocol mProtocol = DomainFactory.getInstance(Biz)); mProtocol.methosA(); I think that this is more flexible and less error prone as the complexity of a classloader approach. -Original Message- From: Ola Berg [mailto:[EMAIL PROTECTED]] Sent: Thursday, December 12, 2002 9:52 AM To: Tomcat Users List Subject: [classloading] How to use URLClassLoader within a servlet Depending on the top level domain, I need to use different versions (jars) of the same API, since the protocol differs. So I need to dynamically load my classes at runtime. Just putting the jars in lib won't work since there are different implementations of the same classes in them. I have to decide in runtime. -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
I would recommend to use a different approach: [snip] Doesn't help since the underlying API (outside of my control) belongs in different jars (same class names, different implementations). Sure, by tweaking I can do as you suggested, but the dynamic class loading will be the most flexible. /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: [classloading] How to use URLClassLoader within a servlet
OK, that's a reason. So you create one instance of the classloader for each protocol/jar ? I think you have to find out where it hangs: - under linux/unix kill -QUIT jvmpid will produce a stacktrace for each thread (per dafault catalina.out) - build extensive logging in your classloader - use a debugger to find ourt what hapens Or you could try to isolate the problem with an example and post that to the list. -Original Message- From: Ola Berg [mailto:[EMAIL PROTECTED]] Sent: Thursday, December 12, 2002 10:30 AM To: Tomcat Users List Subject: Re: [classloading] How to use URLClassLoader within a servlet Doesn't help since the underlying API (outside of my control) belongs in different jars (same class names, different implementations). -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
Ola Berg wrote: I have this problem with using my own (URLClassLoader) class loader in a servlet of mine. The thing is that I am writing a web front end to domain name services (automatic registration of .org, .com. .biz, .info etc domains). Depending on the top level domain, I need to use different versions (jars) of the same API, since the protocol differs. So I need to dynamically load my classes at runtime. Just putting the jars in lib won't work since there are different implementations of the same classes in them. I have to decide in runtime. Using the URLClassLoader in a standalone app works perfectly, when using it in a servlet it just hangs. I suspect the problem lies within the different lookup order used in servlets (as dscribed in the classloader-HOWTO). I can't figure out how to do it. Has anyone experience in the field? I have an analogous case, in which I have a single API for database access, with choice of database (Oracle, MySQL,...) made at run-time. The problem was simply solved using the 'Abstract Factory' pattern. This means that I have two packages (db.MySql, db.Oracle), which both include an implementation of a DBFactory. I then use ClassForName() to load the appropriate implementation, and then call factory methods to instantiate the appropriate classes. Hence, you don't need to bother with custom classloaders, and your design is much 'cleaner' as a result. HTH, Martin -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
I have an analogous case, in which I have a single API for database access, with choice of database (Oracle, MySQL,...) made at run-time. The problem was simply solved using the 'Abstract Factory' pattern. This means that I have two packages (db.MySql, db.Oracle), which both include an implementation of a DBFactory. I then use ClassForName() to load the appropriate implementation, and then call factory methods to instantiate the appropriate classes. But I need to bother with class loaders. The classes have the same name but different implementations. This resides outside of my control. Solution (in the standalone app) is to load the implementations on demand using different URLClassLoaders. /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
Or you could try to isolate the problem with an example and post that to the list. The problem can be stated as ---8--- URL[] urls = new URL[]{ new URL(http://www.myserver.com/jars/myapi-1.2.jar;) }; URLClassLoader cl = new URLClassLoader( urls); //have tried different parents //here it hangs Class c = cl.loadClass( nu.viggo.my.MyClass); ---8--- Above snippet works in standalone app, but not in servlet. Tested with several kinds of URLs (class file directories, jarfiles, http, ftp) same result. Any clues? Craig? Anyone? /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: [classloading] How to use URLClassLoader within a servlet
-Original Message- From: Ola Berg [mailto:[EMAIL PROTECTED]] Sent: Thursday, December 12, 2002 3:52 AM To: Tomcat Users List Subject: [classloading] How to use URLClassLoader within a servlet I have this problem with using my own (URLClassLoader) class loader in a servlet of mine. The thing is that I am writing a web front end to domain name services (automatic registration of .org, .com. .biz, .info etc domains). Depending on the top level domain, I need to use different versions (jars) of the same API, since the protocol differs. So I need to dynamically load my classes at runtime. Just putting the jars in lib won't work since there are different implementations of the same classes in them. I have to decide in runtime. couldn't you use this the 'top level domain' to determine which context to send the request to?. This way each context will have its own version of the library(in its own classloader) and you won't have the conflict. You will have to copy any supporting library to each webapp also, but that's nowhere near the problem you have now. Charlie Using the URLClassLoader in a standalone app works perfectly, when using it in a servlet it just hangs. I suspect the problem lies within the different lookup order used in servlets (as dscribed in the classloader-HOWTO). I can't figure out how to do it. Has anyone experience in the field? /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
As an experiment, I created a directory under WEB-INF called ext and dumped a JAR file in it (commons-cli-1.0.jar). Then I created a servlet that did: URL jarURL = getServletContext().getResource(/WEB-INF/ext/commons-cli-1.0.jar); URL[] urls = { jarURL }; ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader(); URLClassLoader urlClassLoader = new URLClassLoader(urls, ctxClassLoader); String className = org.apache.commons.cli.ParseException; String classResourceName = className.replace('.', '/') + .class; Class cls = urlClassLoader.loadClass(className); System.out.println(URL of + cls.getName() + : + cls.getClassLoader().getResource(classResourceName)); On TC 4.1.16, the output was: URL of org.apache.commons.cli.ParseException: jar:jndi:/localhost/WEB-INF/ext/commons-cli-1.0.jar!/org/apache/commons/cli/ParseException.class Which is just the kind of thing you want, yes? Quoting Ola Berg [EMAIL PROTECTED]: I have an analogous case, in which I have a single API for database access, with choice of database (Oracle, MySQL,...) made at run-time. The problem was simply solved using the 'Abstract Factory' pattern. This means that I have two packages (db.MySql, db.Oracle), which both include an implementation of a DBFactory. I then use ClassForName() to load the appropriate implementation, and then call factory methods to instantiate the appropriate classes. But I need to bother with class loaders. The classes have the same name but different implementations. This resides outside of my control. Solution (in the standalone app) is to load the implementations on demand using different URLClassLoaders. /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- Kris Schneider mailto:[EMAIL PROTECTED] D.O.Tech http://www.dotech.com/ -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: [classloading] How to use URLClassLoader within a servlet
have you looked at WebAppClassloader.java to see how it is implemented in tomcat? Also see the Loader element in server.xml to see if that would help you extend the WebAppLoader.java to implement your own WebAppClassloader Charlie -Original Message- From: Ola Berg [mailto:[EMAIL PROTECTED]] Sent: Thursday, December 12, 2002 6:20 AM To: Tomcat Users List Subject: Re: [classloading] How to use URLClassLoader within a servlet Or you could try to isolate the problem with an example and post that to the list. The problem can be stated as ---8--- URL[] urls = new URL[]{ new URL(http://www.myserver.com/jars/myapi-1.2.jar;) }; URLClassLoader cl = new URLClassLoader( urls); //have tried different parents //here it hangs Class c = cl.loadClass( nu.viggo.my.MyClass); ---8--- Above snippet works in standalone app, but not in servlet. Tested with several kinds of URLs (class file directories, jarfiles, http, ftp) same result. Any clues? Craig? Anyone? /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
couldn't you use this the 'top level domain' to determine which context to send the request to?. Yes of course. That is one of the B plans, should this classloading thing fail. A plan is still dynamic class loading. /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
As an experiment, I created a directory under WEB-INF called ext and dumped a' JAR file in it (commons-cli-1.0.jar). Then I created a servlet that did: [snip] Which is just the kind of thing you want, yes? No, you cheated ;-) You put the jar file in the WEB-INF. Strictly, we want it anywhere on the web. But it is interesting. If one can use different dirs instead of ext/ (org/, info/) etc, in parallel, without creating any conflicts, that could be some kind of solution. /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
Okay, I moved the JAR to $CATALINA_HOME/webapps/ROOT and changed the code to: URL jarURL = new URL(http://gizzard.dotech.com:8080/commons-cli-1.0.jar;); And got as output: URL of org.apache.commons.cli.ParseException: jar:http://gizzard.dotech.com:8080/commons-cli-1.0.jar!/org/apache/commons/cli/ParseException.class I don't see why it wouldn't work in general from any other external URL. Do you need this to work across firewalls? Quoting Ola Berg [EMAIL PROTECTED]: As an experiment, I created a directory under WEB-INF called ext and dumped a' JAR file in it (commons-cli-1.0.jar). Then I created a servlet that did: [snip] Which is just the kind of thing you want, yes? No, you cheated ;-) You put the jar file in the WEB-INF. Strictly, we want it anywhere on the web. But it is interesting. If one can use different dirs instead of ext/ (org/, info/) etc, in parallel, without creating any conflicts, that could be some kind of solution. /O -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- Kris Schneider mailto:[EMAIL PROTECTED] D.O.Tech http://www.dotech.com/ -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: [classloading] How to use URLClassLoader within a servlet
See java/net/URL.java, specifically getURLStreamHandler(String), for an illustration of how Java has handled pluggable handlers since version 1.0. --- Noel -Original Message- From: Ola Berg [mailto:[EMAIL PROTECTED]] Sent: Thursday, December 12, 2002 9:52 AM To: Tomcat Users List Subject: [classloading] How to use URLClassLoader within a servlet Depending on the top level domain, I need to use different versions (jars) of the same API, since the protocol differs. So I need to dynamically load my classes at runtime. Just putting the jars in lib won't work since there are different implementations of the same classes in them. I have to decide in runtime. -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: [classloading] How to use URLClassLoader within a servlet
On Thu, 12 Dec 2002, Ola Berg wrote: Date: Thu, 12 Dec 2002 12:19:35 +0100 From: Ola Berg [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: Tomcat Users List [EMAIL PROTECTED] Subject: Re: [classloading] How to use URLClassLoader within a servlet Or you could try to isolate the problem with an example and post that to the list. The problem can be stated as ---8--- URL[] urls = new URL[]{ new URL(http://www.myserver.com/jars/myapi-1.2.jar;) }; URLClassLoader cl = new URLClassLoader( urls); //have tried different parents //here it hangs Class c = cl.loadClass( nu.viggo.my.MyClass); ---8--- Above snippet works in standalone app, but not in servlet. Tested with several kinds of URLs (class file directories, jarfiles, http, ftp) same result. Any clues? Craig? Anyone? /O When I battle with class loaders, I usually lose too :-). However, If you want to use a remote JAR file in a class loader, shouldn't the syntax of your URL match that defined in the Javadocs for JarURLConnection? Craig -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]