Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
Well, I guess I really am starting to learn a bit more about Tomcat. It is possible to remove the singleton loader and put it back in the application code. I was just trying to do something slick with a single loader. But your answer and the previous one have shown me the error of my way. now I see the light! :-) David Delbecq <[EMAIL PROTECTED]> wrote: THAT is really *not* recommended. Short answer, you go the wrong way in your design. And adding your web-inf/classes to your common classloader will completly break the tomcat behaviour (presence of same classes at 2 levels, some instances are done at one level, some other at another level, and you will have codes like 'instanceof' fail even if class names & packages are same, because 2 sides of check use a different classloader) Long answer, from tomcat docs, about classloader: Bootstrap | System | Common / \ Catalina Shared / \ Webapp1 Webapp2 (Other servlet engine have probably similar structure, separing server level from webapp level and isolating webapps) Webapp2 classloader can load class from webapp2, Shared, Common, System, Bootstrap. This does not go 2 ways, it's a one way road. What you are trying to do is, from Common classloader to load a class inside Webapp2 classloader. Question, how do you expect you singleton loader in common to be able to know which webapp to use and locate it's classloader? 1) Mixing common and webapp level is really *not* a recommended design, i suggest you put your singleton loader inside your webapp's WEB-INF/classes folder. 2) If it's not possible, your singleton classes themselves should be also within common/lib so your singleton loader can see them. 3) If (and only if) what you want to do is actually a factory that reside in common/lib and create instances of object in WEB-INF/lib, and, more over, if and only if, you do this in a Thread that process a client request, you can use Thread.currentThread().getContextClassLoader() because early in the client Http request tomcat set it to classloader of webapp that will process request. One important thing to know in this later scenario is that your singletonloader must *not* keep references to those created instances (that why i spoke about factory not singleton). This is because keeping at common level a reference to an object loaded at webapp level will prevent this webapp's classloader to be garbage collected at redeployed and with it all static instances, which end quickly to visible memory leaks (out of permgen) You scenario, looking at your code, seems to me could be (2), considering you load singletons during context listener event, and that you use server wide constant to tell what to load. It's not webapp specific and as such should not concern webapps. Last but not least, it seems your aimed architecture it to load a set of 'called at initialization' classes in each webapp you deploy. This is strange, as deciding we need a specific service at webapp startup, loaded from classes in webapp, is generally a webapp specific job. It should be done at webapp level, probably using a ServletContextListener configured in web.xml. (http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletContextListener.html) Mike Peremsky a écrit : > The class that is trying to load the singleton (SingletonLoader) is in a > common JAR located at /common/lib/mvpservlet.jar > > The Singletons that I am trying to load can be from ANY app and are in the > WEB-INF/classes folder of whichever application is trying to use the > SingletonLoader. > > > Filip Hanik - Dev Lists wrote: > that work around is probably not what you want. You've just disabled the > ability to reload your app correctly. > Try using another classloader, maybe the > Thread.currentThread().getContextClassLoader() > > where are you storing the class that is trying to load the singleton? it > should be in your webapp as well. > > Filip > > Mike Peremsky wrote: > >> I have resolved this issue, but am wondering if the way I did it is the >> "correct" way to resolve this issue. >> >> I modified the catalina.properties file entry common.loader by adding the >> path to the applications WEB-INF/classes directory, this seems to have >> resolved the issue with finding the class. >> >> >> common.loader=${catalina.home}/common/classes,,${catalina.home}/webapps/myExternalApp/WEB-INF/classes >> >> >> >> I also had to fix a bug in the retrieval of the method (I read the API docs >> incorrectly) >> >> private static final Object OBJECT_ARG_LIST[] = new Object[0]; >> private static final Class CLASS_ARG_LIST[] = new Class[0]; >> >> Method method = singletonClassObj.getMethod(GET_INSTANCE_METHOD, >> CLASS_ARG_LIST); >> method.invoke(null, OBJECT_ARG_LIST); >> >> >> >> Mike Peremsky wrote: >> I tried the modification you suggested (with the correct method name on the >> end) but still with the same results. I also printed out a debug message >> just to see what class loader was being used (not that I
Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
THAT is really *not* recommended. Short answer, you go the wrong way in your design. And adding your web-inf/classes to your common classloader will completly break the tomcat behaviour (presence of same classes at 2 levels, some instances are done at one level, some other at another level, and you will have codes like 'instanceof' fail even if class names & packages are same, because 2 sides of check use a different classloader) Long answer, from tomcat docs, about classloader: Bootstrap | System | Common / \ Catalina Shared / \ Webapp1 Webapp2 (Other servlet engine have probably similar structure, separing server level from webapp level and isolating webapps) Webapp2 classloader can load class from webapp2, Shared, Common, System, Bootstrap. This does not go 2 ways, it's a one way road. What you are trying to do is, from Common classloader to load a class inside Webapp2 classloader. Question, how do you expect you singleton loader in common to be able to know which webapp to use and locate it's classloader? 1) Mixing common and webapp level is really *not* a recommended design, i suggest you put your singleton loader inside your webapp's WEB-INF/classes folder. 2) If it's not possible, your singleton classes themselves should be also within common/lib so your singleton loader can see them. 3) If (and only if) what you want to do is actually a factory that reside in common/lib and create instances of object in WEB-INF/lib, and, more over, if and only if, you do this in a Thread that process a client request, you can use Thread.currentThread().getContextClassLoader() because early in the client Http request tomcat set it to classloader of webapp that will process request. One important thing to know in this later scenario is that your singletonloader must *not* keep references to those created instances (that why i spoke about factory not singleton). This is because keeping at common level a reference to an object loaded at webapp level will prevent this webapp's classloader to be garbage collected at redeployed and with it all static instances, which end quickly to visible memory leaks (out of permgen) You scenario, looking at your code, seems to me could be (2), considering you load singletons during context listener event, and that you use server wide constant to tell what to load. It's not webapp specific and as such should not concern webapps. Last but not least, it seems your aimed architecture it to load a set of 'called at initialization' classes in each webapp you deploy. This is strange, as deciding we need a specific service at webapp startup, loaded from classes in webapp, is generally a webapp specific job. It should be done at webapp level, probably using a ServletContextListener configured in web.xml. (http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletContextListener.html) Mike Peremsky a écrit : > The class that is trying to load the singleton (SingletonLoader) is in a > common JAR located at /common/lib/mvpservlet.jar > > The Singletons that I am trying to load can be from ANY app and are in the > WEB-INF/classes folder of whichever application is trying to use the > SingletonLoader. > > > Filip Hanik - Dev Lists <[EMAIL PROTECTED]> wrote: > that work around is probably not what you want. You've just disabled the > ability to reload your app correctly. > Try using another classloader, maybe the > Thread.currentThread().getContextClassLoader() > > where are you storing the class that is trying to load the singleton? it > should be in your webapp as well. > > Filip > > Mike Peremsky wrote: > >> I have resolved this issue, but am wondering if the way I did it is the >> "correct" way to resolve this issue. >> >> I modified the catalina.properties file entry common.loader by adding the >> path to the applications WEB-INF/classes directory, this seems to have >> resolved the issue with finding the class. >> >> >> common.loader=${catalina.home}/common/classes,,${catalina.home}/webapps/myExternalApp/WEB-INF/classes >> >> >> >> I also had to fix a bug in the retrieval of the method (I read the API docs >> incorrectly) >> >> private static final Object OBJECT_ARG_LIST[] = new Object[0]; >> private static final Class CLASS_ARG_LIST[] = new Class[0]; >> >> Method method = singletonClassObj.getMethod(GET_INSTANCE_METHOD, >> CLASS_ARG_LIST); >> method.invoke(null, OBJECT_ARG_LIST); >> >> >> >> Mike Peremsky wrote: >> I tried the modification you suggested (with the correct method name on the >> end) but still with the same results. I also printed out a debug message >> just to see what class loader was being used (not that I know what to do >> with it :-P ) >> >> log.debug("this class loader: " + >> this.getClass().getClassLoader().getClass().getName()); >> Class singletongClassObj = >> this.getClass().getClassLoader().loadClass(singletonClassName); >> >> The class loa
Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
well there you go, that wont work, http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html take a look at the hierarchy of the tomcat class loaders, and a class can only load up in the tree, not down. so mvpservlet is unable to load your web-inf/classes directory from your description, you got it backwards. the singleton classes should be in common/lib or common/classes, or if you want it clean, shared/lib or shared/classes then the class loading the singleton, would be in WEB-INF/lib or WEB-INF/classes, not the other way around Filip Mike Peremsky wrote: The class that is trying to load the singleton (SingletonLoader) is in a common JAR located at /common/lib/mvpservlet.jar The Singletons that I am trying to load can be from ANY app and are in the WEB-INF/classes folder of whichever application is trying to use the SingletonLoader. Filip Hanik - Dev Lists <[EMAIL PROTECTED]> wrote: that work around is probably not what you want. You've just disabled the ability to reload your app correctly. Try using another classloader, maybe the Thread.currentThread().getContextClassLoader() where are you storing the class that is trying to load the singleton? it should be in your webapp as well. Filip Mike Peremsky wrote: I have resolved this issue, but am wondering if the way I did it is the "correct" way to resolve this issue. I modified the catalina.properties file entry common.loader by adding the path to the applications WEB-INF/classes directory, this seems to have resolved the issue with finding the class. common.loader=${catalina.home}/common/classes,,${catalina.home}/webapps/myExternalApp/WEB-INF/classes I also had to fix a bug in the retrieval of the method (I read the API docs incorrectly) private static final Object OBJECT_ARG_LIST[] = new Object[0]; private static final Class CLASS_ARG_LIST[] = new Class[0]; Method method = singletonClassObj.getMethod(GET_INSTANCE_METHOD, CLASS_ARG_LIST); method.invoke(null, OBJECT_ARG_LIST); Mike Peremsky wrote: I tried the modification you suggested (with the correct method name on the end) but still with the same results. I also printed out a debug message just to see what class loader was being used (not that I know what to do with it :-P ) log.debug("this class loader: " + this.getClass().getClassLoader().getClass().getName()); Class singletongClassObj = this.getClass().getClassLoader().loadClass(singletonClassName); The class loader for the SingletonLoader is: org.apache.catalina.loader.StandardClassLoader. The classes that it is looking for are located in the /apache-tomcat-5.5.23/webapps/myExternalApp/WEB-INF/classes directory. Filip Hanik - Dev Lists wrote: did you try Class singletongClassObj = this.getClass().getClassLoader().loadName(singletonClassName); Filip Mike Peremsky wrote: I think this may be a class loader issue, but am not sure as I have never really worked with them before. I am putting together a JAR file that contains a set of classes to be used throughout a suite of applications. I have a class called SingletonLoader that was working when it was within the main application, but when I broke out the reusable classes into a separate jar file and modified the contextInitialized() method to dynamically load the classes it is failing to fid the classes. The contextInitialized() method is properly reading the class names from the property file (e.g. SINGLETON_LOADER_CLASSES=com.externalApp.singleton.Countries,com.externalApp.singleton.SecurityQuestions) and looping through them, but I always get the following error message when the line Class singletongClassObj = Class.forName(singletonClassName); is executed: Unable to load singleton: com.externalApp.singleton.Countries java.lang.ClassNotFoundException: com.externalApp.singleton.Countries ALL of the singleton classes to be loaded implement the Singleton interface (which has nothing in it, it is just used to denote a class that MUST specify a "public static anyReturnVal getInstance()" method. public class SingletonLoader implements ServletContextListener, SystemConsts { /** * Logger for this class */ private static final Logger log = Logger.getLogger(SingletonLoader.class); private static final String SINGLETON_LOADER_CLASSES = "SINGLETON_LOADER_CLASSES"; private static final String DELIMITER = ","; // This is the method defined private static final String GET_INSTANCE_METHOD = "getInstance"; private static final Object ARG_LIST[] = new Object[0]; /** * Constructs a new SingletonLoader object. */ public SingletonLoader() { } /** * Notification that the web application is ready to process requests. * * Initializes all of the singletons so they are ready for immediate use * after the containet server starts. * * @param sce This is the event object for notifications about changes to the * servlet context of a web application. * */ public void contextInitialized(ServletContextEvent sce) { log.debu
Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
The class that is trying to load the singleton (SingletonLoader) is in a common JAR located at /common/lib/mvpservlet.jar The Singletons that I am trying to load can be from ANY app and are in the WEB-INF/classes folder of whichever application is trying to use the SingletonLoader. Filip Hanik - Dev Lists <[EMAIL PROTECTED]> wrote: that work around is probably not what you want. You've just disabled the ability to reload your app correctly. Try using another classloader, maybe the Thread.currentThread().getContextClassLoader() where are you storing the class that is trying to load the singleton? it should be in your webapp as well. Filip Mike Peremsky wrote: > I have resolved this issue, but am wondering if the way I did it is the > "correct" way to resolve this issue. > > I modified the catalina.properties file entry common.loader by adding the > path to the applications WEB-INF/classes directory, this seems to have > resolved the issue with finding the class. > > > common.loader=${catalina.home}/common/classes,,${catalina.home}/webapps/myExternalApp/WEB-INF/classes > > > > I also had to fix a bug in the retrieval of the method (I read the API docs > incorrectly) > > private static final Object OBJECT_ARG_LIST[] = new Object[0]; > private static final Class CLASS_ARG_LIST[] = new Class[0]; > > Method method = singletonClassObj.getMethod(GET_INSTANCE_METHOD, > CLASS_ARG_LIST); > method.invoke(null, OBJECT_ARG_LIST); > > > > Mike Peremsky wrote: > I tried the modification you suggested (with the correct method name on the > end) but still with the same results. I also printed out a debug message just > to see what class loader was being used (not that I know what to do with it > :-P ) > > log.debug("this class loader: " + > this.getClass().getClassLoader().getClass().getName()); > Class singletongClassObj = > this.getClass().getClassLoader().loadClass(singletonClassName); > > The class loader for the SingletonLoader is: > org.apache.catalina.loader.StandardClassLoader. > > The classes that it is looking for are located in the > > /apache-tomcat-5.5.23/webapps/myExternalApp/WEB-INF/classes directory. > > > > > Filip Hanik - Dev Lists wrote: > did you try > > Class singletongClassObj = > this.getClass().getClassLoader().loadName(singletonClassName); > > Filip > > > Mike Peremsky wrote: > >> I think this may be a class loader issue, but am not sure as I have never >> really worked with them before. I am putting together a JAR file that >> contains a set of classes to be used throughout a suite of applications. I >> have a class called SingletonLoader that was working when it was within the >> main application, but when I broke out the reusable classes into a separate >> jar file and modified the contextInitialized() method to dynamically load >> the classes it is failing to fid the classes. The contextInitialized() >> method is properly reading the class names from the property file (e.g. >> SINGLETON_LOADER_CLASSES=com.externalApp.singleton.Countries,com.externalApp.singleton.SecurityQuestions) >> and looping through them, but I always get the following error message when >> the line >> >> Class singletongClassObj = Class.forName(singletonClassName); >> >> is executed: >> >> Unable to load singleton: com.externalApp.singleton.Countries >> java.lang.ClassNotFoundException: com.externalApp.singleton.Countries >> >> ALL of the singleton classes to be loaded implement the Singleton interface >> (which has nothing in it, it is just used to denote a class that MUST >> specify a "public static anyReturnVal getInstance()" method. >> >> public class SingletonLoader implements ServletContextListener, SystemConsts >> { >> /** >> * Logger for this class >> */ >> private static final Logger log = Logger.getLogger(SingletonLoader.class); >> private static final String SINGLETON_LOADER_CLASSES >> = "SINGLETON_LOADER_CLASSES"; >> private static final String DELIMITER = ","; >> // This is the method defined >> private static final String GET_INSTANCE_METHOD = "getInstance"; >> private static final Object ARG_LIST[] = new Object[0]; >> >> /** >> * Constructs a new SingletonLoader object. >> */ >> public SingletonLoader() { >> } >> >> /** >> * Notification that the web application is ready to process requests. >> * >> * Initializes all of the singletons so they are ready for immediate use >> * after the containet server starts. >> * >> * @param sce This is the event object for notifications about changes to the >> * servlet context of a web application. >> * >> */ >> public void contextInitialized(ServletContextEvent sce) { >> >> log.debug("contextInitialized: BEGIN"); >> String singletons = ExtProperties.getProperty(SYS_PROPS, >> SINGLETON_LOADER_CLASSES); >> >> if (!StringUtils.isNullOrZeroLen(singletons)) { >> DelimitedString ds = new DelimitedString(singletons, DELIMITER); >> int max = ds.size(); >> String singletonClassName = null; >> >> for (int ndx=0; ndx < m
Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
that work around is probably not what you want. You've just disabled the ability to reload your app correctly. Try using another classloader, maybe the Thread.currentThread().getContextClassLoader() where are you storing the class that is trying to load the singleton? it should be in your webapp as well. Filip Mike Peremsky wrote: I have resolved this issue, but am wondering if the way I did it is the "correct" way to resolve this issue. I modified the catalina.properties file entry common.loader by adding the path to the applications WEB-INF/classes directory, this seems to have resolved the issue with finding the class. common.loader=${catalina.home}/common/classes,,${catalina.home}/webapps/myExternalApp/WEB-INF/classes I also had to fix a bug in the retrieval of the method (I read the API docs incorrectly) private static final Object OBJECT_ARG_LIST[] = new Object[0]; private static final Class CLASS_ARG_LIST[] = new Class[0]; Method method = singletonClassObj.getMethod(GET_INSTANCE_METHOD, CLASS_ARG_LIST); method.invoke(null, OBJECT_ARG_LIST); Mike Peremsky <[EMAIL PROTECTED]> wrote: I tried the modification you suggested (with the correct method name on the end) but still with the same results. I also printed out a debug message just to see what class loader was being used (not that I know what to do with it :-P ) log.debug("this class loader: " + this.getClass().getClassLoader().getClass().getName()); Class singletongClassObj = this.getClass().getClassLoader().loadClass(singletonClassName); The class loader for the SingletonLoader is: org.apache.catalina.loader.StandardClassLoader. The classes that it is looking for are located in the /apache-tomcat-5.5.23/webapps/myExternalApp/WEB-INF/classes directory. Filip Hanik - Dev Lists wrote: did you try Class singletongClassObj = this.getClass().getClassLoader().loadName(singletonClassName); Filip Mike Peremsky wrote: I think this may be a class loader issue, but am not sure as I have never really worked with them before. I am putting together a JAR file that contains a set of classes to be used throughout a suite of applications. I have a class called SingletonLoader that was working when it was within the main application, but when I broke out the reusable classes into a separate jar file and modified the contextInitialized() method to dynamically load the classes it is failing to fid the classes. The contextInitialized() method is properly reading the class names from the property file (e.g. SINGLETON_LOADER_CLASSES=com.externalApp.singleton.Countries,com.externalApp.singleton.SecurityQuestions) and looping through them, but I always get the following error message when the line Class singletongClassObj = Class.forName(singletonClassName); is executed: Unable to load singleton: com.externalApp.singleton.Countries java.lang.ClassNotFoundException: com.externalApp.singleton.Countries ALL of the singleton classes to be loaded implement the Singleton interface (which has nothing in it, it is just used to denote a class that MUST specify a "public static anyReturnVal getInstance()" method. public class SingletonLoader implements ServletContextListener, SystemConsts { /** * Logger for this class */ private static final Logger log = Logger.getLogger(SingletonLoader.class); private static final String SINGLETON_LOADER_CLASSES = "SINGLETON_LOADER_CLASSES"; private static final String DELIMITER = ","; // This is the method defined private static final String GET_INSTANCE_METHOD = "getInstance"; private static final Object ARG_LIST[] = new Object[0]; /** * Constructs a new SingletonLoader object. */ public SingletonLoader() { } /** * Notification that the web application is ready to process requests. * * Initializes all of the singletons so they are ready for immediate use * after the containet server starts. * * @param sce This is the event object for notifications about changes to the * servlet context of a web application. * */ public void contextInitialized(ServletContextEvent sce) { log.debug("contextInitialized: BEGIN"); String singletons = ExtProperties.getProperty(SYS_PROPS, SINGLETON_LOADER_CLASSES); if (!StringUtils.isNullOrZeroLen(singletons)) { DelimitedString ds = new DelimitedString(singletons, DELIMITER); int max = ds.size(); String singletonClassName = null; for (int ndx=0; ndx < max; ndx++) { try { singletonClassName = ds.getEntry(ndx); log.debug("Get singletonClassName: " + singletonClassName); // Get the singleton class to load Class singletongClassObj = Class.forName(singletonClassName); log.debug("singletongClassObj: " + singletongClassObj); Method method = singletongClassObj.getMethod(GET_INSTANCE_METHOD, singletongClassObj); method.invoke(null, ARG_LIST); } catch (Exception e) { log.error("Unable to load singleton: " + singletonClassName, e); } } } log.debug("contextInitiali
Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
I have resolved this issue, but am wondering if the way I did it is the "correct" way to resolve this issue. I modified the catalina.properties file entry common.loader by adding the path to the applications WEB-INF/classes directory, this seems to have resolved the issue with finding the class. common.loader=${catalina.home}/common/classes,,${catalina.home}/webapps/myExternalApp/WEB-INF/classes I also had to fix a bug in the retrieval of the method (I read the API docs incorrectly) private static final Object OBJECT_ARG_LIST[] = new Object[0]; private static final Class CLASS_ARG_LIST[] = new Class[0]; Method method = singletonClassObj.getMethod(GET_INSTANCE_METHOD, CLASS_ARG_LIST); method.invoke(null, OBJECT_ARG_LIST); Mike Peremsky <[EMAIL PROTECTED]> wrote: I tried the modification you suggested (with the correct method name on the end) but still with the same results. I also printed out a debug message just to see what class loader was being used (not that I know what to do with it :-P ) log.debug("this class loader: " + this.getClass().getClassLoader().getClass().getName()); Class singletongClassObj = this.getClass().getClassLoader().loadClass(singletonClassName); The class loader for the SingletonLoader is: org.apache.catalina.loader.StandardClassLoader. The classes that it is looking for are located in the /apache-tomcat-5.5.23/webapps/myExternalApp/WEB-INF/classes directory. Filip Hanik - Dev Lists wrote: did you try Class singletongClassObj = this.getClass().getClassLoader().loadName(singletonClassName); Filip Mike Peremsky wrote: > I think this may be a class loader issue, but am not sure as I have never > really worked with them before. I am putting together a JAR file that > contains a set of classes to be used throughout a suite of applications. I > have a class called SingletonLoader that was working when it was within the > main application, but when I broke out the reusable classes into a separate > jar file and modified the contextInitialized() method to dynamically load the > classes it is failing to fid the classes. The contextInitialized() method is > properly reading the class names from the property file (e.g. > SINGLETON_LOADER_CLASSES=com.externalApp.singleton.Countries,com.externalApp.singleton.SecurityQuestions) > and looping through them, but I always get the following error message when > the line > > Class singletongClassObj = Class.forName(singletonClassName); > > is executed: > > Unable to load singleton: com.externalApp.singleton.Countries > java.lang.ClassNotFoundException: com.externalApp.singleton.Countries > > ALL of the singleton classes to be loaded implement the Singleton interface > (which has nothing in it, it is just used to denote a class that MUST specify > a "public static anyReturnVal getInstance()" method. > > public class SingletonLoader implements ServletContextListener, SystemConsts { > /** > * Logger for this class > */ > private static final Logger log = Logger.getLogger(SingletonLoader.class); > private static final String SINGLETON_LOADER_CLASSES > = "SINGLETON_LOADER_CLASSES"; > private static final String DELIMITER = ","; > // This is the method defined > private static final String GET_INSTANCE_METHOD = "getInstance"; > private static final Object ARG_LIST[] = new Object[0]; > > /** > * Constructs a new SingletonLoader object. > */ > public SingletonLoader() { > } > > /** > * Notification that the web application is ready to process requests. > * > * Initializes all of the singletons so they are ready for immediate use > * after the containet server starts. > * > * @param sce This is the event object for notifications about changes to the > * servlet context of a web application. > * > */ > public void contextInitialized(ServletContextEvent sce) { > > log.debug("contextInitialized: BEGIN"); > String singletons = ExtProperties.getProperty(SYS_PROPS, > SINGLETON_LOADER_CLASSES); > > if (!StringUtils.isNullOrZeroLen(singletons)) { > DelimitedString ds = new DelimitedString(singletons, DELIMITER); > int max = ds.size(); > String singletonClassName = null; > > for (int ndx=0; ndx < max; ndx++) { > try { > singletonClassName = ds.getEntry(ndx); > log.debug("Get singletonClassName: " + singletonClassName); > // Get the singleton class to load > Class singletongClassObj = Class.forName(singletonClassName); > log.debug("singletongClassObj: " + singletongClassObj); > Method method = singletongClassObj.getMethod(GET_INSTANCE_METHOD, > singletongClassObj); > method.invoke(null, ARG_LIST); > > } catch (Exception e) { > log.error("Unable to load singleton: " + singletonClassName, e); > } > } > } > log.debug("contextInitialized: END"); > } > > /** > * Notification that the servlet context is about to be shut down. > * > * @param sce the ServletContextEvent > */ > public void contextDestroyed(ServletCo
Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
I tried the modification you suggested (with the correct method name on the end) but still with the same results. I also printed out a debug message just to see what class loader was being used (not that I know what to do with it :-P ) log.debug("this class loader: " + this.getClass().getClassLoader().getClass().getName()); Class singletongClassObj = this.getClass().getClassLoader().loadClass(singletonClassName); The class loader for the SingletonLoader is: org.apache.catalina.loader.StandardClassLoader. The classes that it is looking for are located in the /apache-tomcat-5.5.23/webapps/myExternalApp/WEB-INF/classes directory. Filip Hanik - Dev Lists <[EMAIL PROTECTED]> wrote: did you try Class singletongClassObj = this.getClass().getClassLoader().loadName(singletonClassName); Filip Mike Peremsky wrote: > I think this may be a class loader issue, but am not sure as I have never > really worked with them before. I am putting together a JAR file that > contains a set of classes to be used throughout a suite of applications. I > have a class called SingletonLoader that was working when it was within the > main application, but when I broke out the reusable classes into a separate > jar file and modified the contextInitialized() method to dynamically load the > classes it is failing to fid the classes. The contextInitialized() method is > properly reading the class names from the property file (e.g. > SINGLETON_LOADER_CLASSES=com.externalApp.singleton.Countries,com.externalApp.singleton.SecurityQuestions) > and looping through them, but I always get the following error message when > the line > > Class singletongClassObj = Class.forName(singletonClassName); > > is executed: > > Unable to load singleton: com.externalApp.singleton.Countries > java.lang.ClassNotFoundException: com.externalApp.singleton.Countries > > ALL of the singleton classes to be loaded implement the Singleton interface > (which has nothing in it, it is just used to denote a class that MUST specify > a "public static anyReturnVal getInstance()" method. > > public class SingletonLoader implements ServletContextListener, SystemConsts { > /** > * Logger for this class > */ > private static final Logger log = Logger.getLogger(SingletonLoader.class); > private static final String SINGLETON_LOADER_CLASSES > = "SINGLETON_LOADER_CLASSES"; > private static final String DELIMITER = ","; > // This is the method defined > private static final String GET_INSTANCE_METHOD = "getInstance"; > private static final Object ARG_LIST[] = new Object[0]; > > /** > * Constructs a new SingletonLoader object. > */ > public SingletonLoader() { > } > > /** > * Notification that the web application is ready to process requests. > * > * Initializes all of the singletons so they are ready for immediate use > * after the containet server starts. > * > * @param sce This is the event object for notifications about changes to the > * servlet context of a web application. > * > */ > public void contextInitialized(ServletContextEvent sce) { > > log.debug("contextInitialized: BEGIN"); > String singletons = ExtProperties.getProperty(SYS_PROPS, > SINGLETON_LOADER_CLASSES); > > if (!StringUtils.isNullOrZeroLen(singletons)) { > DelimitedString ds = new DelimitedString(singletons, DELIMITER); > int max = ds.size(); > String singletonClassName = null; > > for (int ndx=0; ndx < max; ndx++) { > try { > singletonClassName = ds.getEntry(ndx); > log.debug("Get singletonClassName: " + singletonClassName); > // Get the singleton class to load > Class singletongClassObj = Class.forName(singletonClassName); > log.debug("singletongClassObj: " + singletongClassObj); > Method method = singletongClassObj.getMethod(GET_INSTANCE_METHOD, > singletongClassObj); > method.invoke(null, ARG_LIST); > > } catch (Exception e) { > log.error("Unable to load singleton: " + singletonClassName, e); > } > } > } > log.debug("contextInitialized: END"); > } > > /** > * Notification that the servlet context is about to be shut down. > * > * @param sce the ServletContextEvent > */ > public void contextDestroyed(ServletContextEvent sce) { > } > } > > Example of the Countries singleton > > > public class Countries implements DbConsts, Singleton { > private static Logger log = Logger.getLogger(Countries.class); > > > > /** Creates a new instance of Countries */ > private Countries() { > refreshData(); > } > > /** > * Returns the single instance of this class. > * > * @return the instance of this class. > */ > public static Countries getInstance() { > if (instance == null) { > synchronized (Countries.class) { > if (instance == null) { > instance = new Countries(); > } > } > } > return instance; > } > > > } > > > - > Be a better Globetrotter. Get better travel answers from someone who knows. > Yahoo! Answers - Check it out. > > -
Re: Cannot get SingleonLoader (from jar) to find classes outside JAR
did you try Class singletongClassObj = this.getClass().getClassLoader().loadName(singletonClassName); Filip Mike Peremsky wrote: I think this may be a class loader issue, but am not sure as I have never really worked with them before. I am putting together a JAR file that contains a set of classes to be used throughout a suite of applications. I have a class called SingletonLoader that was working when it was within the main application, but when I broke out the reusable classes into a separate jar file and modified the contextInitialized() method to dynamically load the classes it is failing to fid the classes. The contextInitialized() method is properly reading the class names from the property file (e.g. SINGLETON_LOADER_CLASSES=com.externalApp.singleton.Countries,com.externalApp.singleton.SecurityQuestions) and looping through them, but I always get the following error message when the line Class singletongClassObj = Class.forName(singletonClassName); is executed: Unable to load singleton: com.externalApp.singleton.Countries java.lang.ClassNotFoundException: com.externalApp.singleton.Countries ALL of the singleton classes to be loaded implement the Singleton interface (which has nothing in it, it is just used to denote a class that MUST specify a "public static anyReturnVal getInstance()" method. public class SingletonLoader implements ServletContextListener, SystemConsts { /** * Logger for this class */ private static final Logger log = Logger.getLogger(SingletonLoader.class); private static final String SINGLETON_LOADER_CLASSES = "SINGLETON_LOADER_CLASSES"; private static final String DELIMITER = ","; // This is the method defined private static final String GET_INSTANCE_METHOD = "getInstance"; private static final Object ARG_LIST[] = new Object[0]; /** * Constructs a new SingletonLoader object. */ public SingletonLoader() { } /** * Notification that the web application is ready to process requests. * * Initializes all of the singletons so they are ready for immediate use * after the containet server starts. * * @param sce This is the event object for notifications about changes to the *servlet context of a web application. * */ public void contextInitialized(ServletContextEvent sce) { log.debug("contextInitialized: BEGIN"); String singletons = ExtProperties.getProperty(SYS_PROPS, SINGLETON_LOADER_CLASSES); if (!StringUtils.isNullOrZeroLen(singletons)) { DelimitedString ds = new DelimitedString(singletons, DELIMITER); int max = ds.size(); String singletonClassName = null; for (int ndx=0; ndx < max; ndx++) { try { singletonClassName = ds.getEntry(ndx); log.debug("Get singletonClassName: " + singletonClassName); // Get the singleton class to load Class singletongClassObj = Class.forName(singletonClassName); log.debug("singletongClassObj: " + singletongClassObj); Method method = singletongClassObj.getMethod(GET_INSTANCE_METHOD, singletongClassObj); method.invoke(null, ARG_LIST); } catch (Exception e) { log.error("Unable to load singleton: " + singletonClassName, e); } } } log.debug("contextInitialized: END"); } /** * Notification that the servlet context is about to be shut down. * * @param sce the ServletContextEvent */ public void contextDestroyed(ServletContextEvent sce) { } } Example of the Countries singleton public class Countries implements DbConsts, Singleton { private static Logger log = Logger.getLogger(Countries.class); /** Creates a new instance of Countries */ private Countries() { refreshData(); } /** * Returns the single instance of this class. * * @return the instance of this class. */ public static Countries getInstance() { if (instance == null) { synchronized (Countries.class) { if (instance == null) { instance = new Countries(); } } } return instance; } } - Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out. No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.467 / Virus Database: 269.7.1/805 - Release Date: 5/15/2007 10:47 AM - To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional comma
Cannot get SingleonLoader (from jar) to find classes outside JAR
I think this may be a class loader issue, but am not sure as I have never really worked with them before. I am putting together a JAR file that contains a set of classes to be used throughout a suite of applications. I have a class called SingletonLoader that was working when it was within the main application, but when I broke out the reusable classes into a separate jar file and modified the contextInitialized() method to dynamically load the classes it is failing to fid the classes. The contextInitialized() method is properly reading the class names from the property file (e.g. SINGLETON_LOADER_CLASSES=com.externalApp.singleton.Countries,com.externalApp.singleton.SecurityQuestions) and looping through them, but I always get the following error message when the line Class singletongClassObj = Class.forName(singletonClassName); is executed: Unable to load singleton: com.externalApp.singleton.Countries java.lang.ClassNotFoundException: com.externalApp.singleton.Countries ALL of the singleton classes to be loaded implement the Singleton interface (which has nothing in it, it is just used to denote a class that MUST specify a "public static anyReturnVal getInstance()" method. public class SingletonLoader implements ServletContextListener, SystemConsts { /** * Logger for this class */ private static final Logger log = Logger.getLogger(SingletonLoader.class); private static final String SINGLETON_LOADER_CLASSES = "SINGLETON_LOADER_CLASSES"; private static final String DELIMITER = ","; // This is the method defined private static final String GET_INSTANCE_METHOD = "getInstance"; private static final Object ARG_LIST[] = new Object[0]; /** * Constructs a new SingletonLoader object. */ public SingletonLoader() { } /** * Notification that the web application is ready to process requests. * * Initializes all of the singletons so they are ready for immediate use * after the containet server starts. * * @param sce This is the event object for notifications about changes to the *servlet context of a web application. * */ public void contextInitialized(ServletContextEvent sce) { log.debug("contextInitialized: BEGIN"); String singletons = ExtProperties.getProperty(SYS_PROPS, SINGLETON_LOADER_CLASSES); if (!StringUtils.isNullOrZeroLen(singletons)) { DelimitedString ds = new DelimitedString(singletons, DELIMITER); int max = ds.size(); String singletonClassName = null; for (int ndx=0; ndx < max; ndx++) { try { singletonClassName = ds.getEntry(ndx); log.debug("Get singletonClassName: " + singletonClassName); // Get the singleton class to load Class singletongClassObj = Class.forName(singletonClassName); log.debug("singletongClassObj: " + singletongClassObj); Method method = singletongClassObj.getMethod(GET_INSTANCE_METHOD, singletongClassObj); method.invoke(null, ARG_LIST); } catch (Exception e) { log.error("Unable to load singleton: " + singletonClassName, e); } } } log.debug("contextInitialized: END"); } /** * Notification that the servlet context is about to be shut down. * * @param sce the ServletContextEvent */ public void contextDestroyed(ServletContextEvent sce) { } } Example of the Countries singleton public class Countries implements DbConsts, Singleton { private static Logger log = Logger.getLogger(Countries.class); /** Creates a new instance of Countries */ private Countries() { refreshData(); } /** * Returns the single instance of this class. * * @return the instance of this class. */ public static Countries getInstance() { if (instance == null) { synchronized (Countries.class) { if (instance == null) { instance = new Countries(); } } } return instance; } } - Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out.