Re: Cannot get SingleonLoader (from jar) to find classes outside JAR

2007-05-22 Thread Mike Peremsky
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

2007-05-22 Thread David Delbecq
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

2007-05-22 Thread Filip Hanik - Dev Lists

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

2007-05-22 Thread Mike Peremsky
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

2007-05-22 Thread Filip Hanik - Dev Lists
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

2007-05-21 Thread Mike Peremsky
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

2007-05-21 Thread Mike Peremsky
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

2007-05-21 Thread Filip Hanik - Dev Lists

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

2007-05-21 Thread Mike Peremsky
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.