Re: Jsp class loader issue in Tomcat 7

2012-11-15 Thread Duc Trung TRAN
Konstantin,

Does it means it's a bad thing to use jsp as templating inside a webapp?
And it's normal that it breaks *other* applications but not the application
itself? I would expect the opposite scenario.

Thanks and regards
Trung


2012/11/15 Konstantin Kolinko knst.koli...@gmail.com

 2012/11/14 Christopher Schultz ch...@christopherschultz.net:
 
  Do you have any idea why old jasper-compiler (used inside an
  application) provoke errors to other applications? Is it a bug? Or
  is there some additional config to make it works?
 
  Oh, this breaks *other* applications? There may be some weirdness,
  here, because Tomcat internals might be polluted by classes loaded
  from a particular webapp. That definitely shouldn't happen if we can
  help it.
 

 It is a feature.

 If your webapps are bad citizens and do stupid things or you need
 protection from them, run with SecurityManager being enabled.

 Unless you run with SecurityManager, there is no protection against
 any webapp messing up with Tomcat internals, Java internals, or
 messing up with your operating system as a whole (limited only by the
 rights that tomcat user has).

 Note that if you run with SecurityManager, you have to pay the
 performance price for all those little checks that it does.


 Best regards,
 Konstantin Kolinko

 -
 To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
 For additional commands, e-mail: users-h...@tomcat.apache.org




Re: Jsp class loader issue in Tomcat 7

2012-11-15 Thread Konstantin Kolinko
2012/11/15 Duc Trung TRAN ductrung.t...@gmail.com:
 Konstantin,

 Does it means it's a bad thing to use jsp as templating inside a webapp?

It is bad thing to bundle Tomcat components inside web applications.
You should never do that. [1] should explain why.

[1] and [2] should explain why things are different between 5.5 and 6.07.0.

[1] http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
[2] http://tomcat.apache.org/migration-6.html#Shared_libraries

 And it's normal that it breaks *other* applications but not the application
 itself? I would expect the opposite scenario.

Use a SecurityManager and you will get that opposite scenario.

In 5.5 the server components are more isolated from the web
applications, due to having a separate server classloader. It was
considered a waste, because it does not provide any security by itself
unless you really run with a SecurityManager.

Note that in Tomcat 6  7 (and in Tomcat 5.5 in webapps that have
Context privileged=true)  the server classes are directly visible
from the webapp.  There is no need to bundle such jars in your
application.


 2012/11/15 Konstantin Kolinko knst.koli...@gmail.com

 2012/11/14 Christopher Schultz ch...@christopherschultz.net:
 
  Do you have any idea why old jasper-compiler (used inside an
  application) provoke errors to other applications? Is it a bug? Or
  is there some additional config to make it works?
 
  Oh, this breaks *other* applications? There may be some weirdness,
  here, because Tomcat internals might be polluted by classes loaded
  from a particular webapp. That definitely shouldn't happen if we can
  help it.
 

 It is a feature.

 If your webapps are bad citizens and do stupid things or you need
 protection from them, run with SecurityManager being enabled.

 Unless you run with SecurityManager, there is no protection against
 any webapp messing up with Tomcat internals, Java internals, or
 messing up with your operating system as a whole (limited only by the
 rights that tomcat user has).

 Note that if you run with SecurityManager, you have to pay the
 performance price for all those little checks that it does.


 Best regards,
 Konstantin Kolinko


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Jsp class loader issue in Tomcat 7

2012-11-14 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Trung,

On 11/14/12 10:18 AM, Duc Trung TRAN wrote:
 We are trying to migrate Tomcat 5.5 to Tomcat 7. And We have
 issues in an old application which make use of JspC class. In fact,
 this application has an internal jsp templating and use JspC to
 generate java files from templates. So it has an old version of 
 jasper-compiler.jar in it WEB-INF/lib.

Stop right there.

You can't use an older JSP compiler with a newer version of Tomcat:
the JSP compiler references all kinds of Tomcat internal stuff that
isn't compatible across versions (sometimes even across minor releases
like x.y.1). You will have to update your compiler JAR in order for
any of this to work.

 In Tomcat 7, this application works but not all other
 applications. There are errors as below.
 
 SEVERE: Servlet.service() for servlet [jsp] in context with path
 [] threw exception [java.lang.AbstractMethodError:

Yep, that's the kind of stuff that will happen to you if you have
mismatched versions.

 I suppose there is a classloader issue when we use old version of 
 jasper compiler (???).

Perhaps, but the best thing to do would be to upgrade.

 Because when we remove the old jasper-compiler.jar, all other 
 applications work but not the former :(. It reference indeed an old
 method (JspC.setLog) which is removed in the new version of JspC.
 And we don't have the source (only binary) of the application to
 make change.

How big is the application? Perhaps you could decompile the class that
calls JspC.setLog, modify it, recompile it and put it back into your
application. You could even do it as a separate JAR file earlier in
the CLASSPATH. The best way to do that, actually, is to put the
patched version into WEB-INF/classes because those take precedence
over classes in WEB-INF/lib/*.jar.

 Do you have any idea why old jasper-compiler (used inside an 
 application) provoke errors to other applications? Is it a bug? Or 
 is there some additional config to make it works?

Oh, this breaks *other* applications? There may be some weirdness,
here, because Tomcat internals might be polluted by classes loaded
from a particular webapp. That definitely shouldn't happen if we can
help it.

- -chris
-BEGIN PGP SIGNATURE-
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

iEYEARECAAYFAlCj2H4ACgkQ9CaO5/Lv0PDbTwCggwSbRl3hoD/4jLkk2RvVEDry
MYMAoKVBo0Xrsb/BIR6wVj+uVheO2llH
=UMXY
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: Jsp class loader issue in Tomcat 7

2012-11-14 Thread Konstantin Kolinko
2012/11/14 Christopher Schultz ch...@christopherschultz.net:

 Do you have any idea why old jasper-compiler (used inside an
 application) provoke errors to other applications? Is it a bug? Or
 is there some additional config to make it works?

 Oh, this breaks *other* applications? There may be some weirdness,
 here, because Tomcat internals might be polluted by classes loaded
 from a particular webapp. That definitely shouldn't happen if we can
 help it.


It is a feature.

If your webapps are bad citizens and do stupid things or you need
protection from them, run with SecurityManager being enabled.

Unless you run with SecurityManager, there is no protection against
any webapp messing up with Tomcat internals, Java internals, or
messing up with your operating system as a whole (limited only by the
rights that tomcat user has).

Note that if you run with SecurityManager, you have to pay the
performance price for all those little checks that it does.


Best regards,
Konstantin Kolinko

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



RE: JSP class loader

2006-07-26 Thread Nikita Belov
Chris, 

 As article says, container drops all reference to classloader during
 web-app undeploy. This allows GC to remove classloader and free PermGen.
 In our system, JSP deployed inside web-app without web-app
 redeply. So references to ClassLoader aren't dropped.

Aah, I didn't realize that you were doing this. So, you basically
maintain your own versioning for each JSP? 

Yes. New JSP deployed to different directory.

If I request that a JSP job
be run several times, each run gets its own class compiled and loaded?

I think yes. Obsolete classes removed only on web-app undeploy.

This seems a little kludgey. You are you using JSP as a batch processing
platform?

What do you mean batch processing?

 I see, threre are two possible ways for now: modify jsp servlet as I
 going to before or create web-app for each business process and redeploy
 it when new JSP arrived.

I realize that you are probably required to work within the boundaries
of a pre-existing system, 

Our system is the platform for other applications (as Tomcat it-self). 
Therefore, it can't be pre-existed.

--
Nikita



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: JSP class loader

2006-07-25 Thread Nikita Belov
Chris,

 I work on application which allows user to deploy/undeploy large 
 number of the JSP pages to AppServer (JBoss 4.03sp1 + Tomcat 5.5). 
 Standard Tomcat class loader caches classes for all deployed JSP 
 internally and never clean its cache. This brings JVM to PermGen 
 overflow error after several days of system work.

Ouch. Are you saying that the sheer number of classes in your system 
is overflowing your memory? 

Yes.

That doesn't seem likely.

After tomcat compiles your JSP, it loads the resulting class and
executes it like a servlet.

I know.

If you have an option enabled, it will detect updated JSPs, re-compile
them, and reload them. It is certainly possible that when this happens,
Tomcat discards the entire ClassLoader and starts fresh. In that case,
if you have 10,000 JSPs, then each time you reload, you'll get 10,000
more classes loaded into memory. If this happens enough times, you'll
run out of memory since Java does not clean up old, unused classes in
memory.

I have made some research. Looks like JVM unloads classes from PermGen, 
when classloader instance, used for loading these classes, is destroyed 
by GC. See program attached to the letter. It simply loads classes from
specified dir. This program is intended to be monitored by jconsole.

Is this the behavior you are describing? 

Yes.

If so, then you can't fix the
problem by writing your own JSP compiler and/or ClassLoader. 

I guess loading each JSP class by separate classloader instance 
will fix the problem. Classloader will be created when HTTP request 
recived and no one reference on this classloader instance will be 
stored during request processing, so it can be destroyed by GC.

Your best bet is not to modify your JSPs and have them re-loaded.

Is this in a development setting or production? I would say that 
having JSP reloading turned on in production is a mistake.

I am working on system for business processes processing. Each 
business process can be deployed and launched by user many times. 
Business process can contain JSP(JSF) pages, also it can contain 
Java-scriplets (POJO classes) with business logic. Each scriplet is 
loaded with separate classloader and therefore successfully unloaded 
from PermGen when classloader destroyed. All JSP classes are loaded 
by the one Tomcat classloader and can't be unloaded from memory. 
This is the problem.

Any ideas?

--
Nikita
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

public class JTest {
	
	/**
	 * Load class from specified dir
	 */
	private static class SimpleClassLoader extends ClassLoader {
		private String classPath = null;
		
		public SimpleClassLoader(String classPath) {
			this.classPath = classPath;
		}
	
		private byte[] loadClassData(File f) throws IOException {
	FileChannel in = new FileInputStream(f).getChannel();
	ByteBuffer buf = ByteBuffer.allocate((int) in.size());
	in.read(buf);
	in.close();
	return buf.array();
	}

		public Class findClass(String name) throws ClassNotFoundException {
			try {
System.out.println(Loading  + name);
String classFileName = name.replace('.', '/') + .class;
byte[] buf = loadClassData(new File(classPath, classFileName));
return defineClass(name, buf, 0, buf.length);
			}
			catch (Exception e) {
	throw new ClassNotFoundException(name);
			}
		}
	}

	// Any directory with large number of classes.
	private final static String CLASS_PATH = C:\\Trash\\cp;
	
	private static ArrayList clArr = new ArrayList();
	
	/**
	 * Recursively load classes from CLASS_PATH dir and its subdirs
	 */
static void loadClasses(File dir, String pak) throws Exception {
File[] files = dir.listFiles();
if (files != null) {
for (int i = 0; i  files.length; i++) {
if (files[i].isDirectory()) {
	loadClasses(files[i], pak + files[i].getName() + .);
}
else {
	String fname = files[i].getName();
	fname = fname.substring(0, fname.indexOf('.'));
	SimpleClassLoader classLoader = new SimpleClassLoader(CLASS_PATH);
	classLoader.loadClass(pak + fname);
	
	// uncomment following line to disallow GC finalize 
	// SimpleClassLoader instances and free PermGen 
	//clArr.add(classLoader);
	
	Thread.sleep(50); // for better visualization
}
}
}
}

public static void main(String[] args) throws Exception {
System.out.println(Start);
	Thread.sleep(1); // timeout to start jconsole
	
System.out.println(Begin classes loading);
	loadClasses(new File(CLASS_PATH), );
System.out.println(Classes loading completed);

	

Re: JSP class loader

2006-07-25 Thread Christopher Schultz
Nikita,

 If so, then you can't fix the
 problem by writing your own JSP compiler and/or ClassLoader. 
 
 I guess loading each JSP class by separate classloader instance 
 will fix the problem. Classloader will be created when HTTP request 
 recived and no one reference on this classloader instance will be 
 stored during request processing, so it can be destroyed by GC.

I read through your ClassLoader. It doesn't look like it will compile,
but I'll assume that it was just a copy/paste problem into your message.

I'm not sure what your ClassLoader does differently than any other
ClassLoader; what have you added? If you haven't changed anything, then
it's possible that your classloaders are not being GC'd:
http://opensource2.atlassian.com/confluence/spring/pages/viewpage.action?pageId=2669

 I am working on system for business processes processing. Each 
 business process can be deployed and launched by user many times. 
 Business process can contain JSP(JSF) pages, also it can contain 
 Java-scriplets (POJO classes) with business logic. Each scriplet is 
 loaded with separate classloader and therefore successfully unloaded 
 from PermGen when classloader destroyed.

Do you use your own (hand-written) ClassLoader for the scriptlets, or
one that comes with the JDK?

Someone with more knowledge of Tomcat's internal workings would have to
confirm the behavior of Tomcat when a JSP changes and must be
recompiled: is the ClassLoader for all JSPs discarded, or is there a
separate ClassLoader for each JSP?

I'm guessing that the ClassLoader itself is not your problem, but other
objects retaining references to objects and classes loaded by it. I
encourage you to read through the article I included above to see if any
of the known offenders could possibly be affecting you -- particularly
the introspection caches.

 All JSP classes are loaded 
 by the one Tomcat classloader and can't be unloaded from memory. 
 This is the problem.

I think they /can/ be unloaded from memory, but again, I'm not exactly
sure. This might be a question to ask on the Tomcat developer mailing
list. If Tomcat's ClassLoader really does not discard old compiled JSP
classes, then you really might have to hack the JSP compiler and/or
loader (if they are different) to separate each JSP into its own
ClassLoader.

I'm very interested to see how this turns out.

-chris




signature.asc
Description: OpenPGP digital signature


RE: JSP class loader

2006-07-25 Thread Nikita Belov
Chris,

 If so, then you can't fix the
 problem by writing your own JSP compiler and/or ClassLoader.

 I guess loading each JSP class by separate classloader instance
 will fix the problem. Classloader will be created when HTTP request
 recived and no one reference on this classloader instance will be
 stored during request processing, so it can be destroyed by GC.

I read through your ClassLoader. It doesn't look like it will compile,

Why? It were compiled and run on my PC.

but I'll assume that it was just a copy/paste problem into your message.

I'm not sure what your ClassLoader does differently than any other
ClassLoader; what have you added? If you haven't changed anything, then
it's possible that your classloaders are not being GC'd:
http://opensource2.atlassian.com/confluence/spring/pages/viewpage.action?
pageId=2669

As article says, container drops all reference to classloader during 
web-app undeploy. This allows GC to remove classloader and free PermGen.
In our system, JSP deployed inside web-app without web-app
redeply. So references to ClassLoader aren't dropped. It is not 
possible to redeploy web-app, when new JSP arrived, however may be 
we can create separate web-apps for each business process, and 
redeploy it. I will think about it...


 I am working on system for business processes processing. Each
 business process can be deployed and launched by user many times.
 Business process can contain JSP(JSF) pages, also it can contain
 Java-scriplets (POJO classes) with business logic. Each scriplet is
 loaded with separate classloader and therefore successfully unloaded
 from PermGen when classloader destroyed.

Do you use your own (hand-written) ClassLoader for the scriptlets, or
one that comes with the JDK?

Yes. It is our own classloader.


Someone with more knowledge of Tomcat's internal workings would have to
confirm the behavior of Tomcat when a JSP changes and must be
recompiled: is the ClassLoader for all JSPs discarded, or is there a
separate ClassLoader for each JSP?

Looks like Tomcat create classloader for each web-app.


I'm guessing that the ClassLoader itself is not your problem, but other
objects retaining references to objects and classes loaded by it. I
encourage you to read through the article I included above to see if any
of the known offenders could possibly be affecting you -- particularly
the introspection caches.

 All JSP classes are loaded
 by the one Tomcat classloader and can't be unloaded from memory.
 This is the problem.

I think they /can/ be unloaded from memory, but again, I'm not exactly
sure. This might be a question to ask on the Tomcat developer mailing
list. If Tomcat's ClassLoader really does not discard old compiled JSP
classes, 

Looks like these classes will be removed from PermGen with classloader 
after web-app undeploy.

then you really might have to hack the JSP compiler and/or
loader (if they are different) to separate each JSP into its own
ClassLoader.

I'm very interested to see how this turns out.

I see, threre are two possible ways for now: modify jsp servlet as I 
going to before or create web-app for each business process and redeploy 
it when new JSP arrived. 

--
Nikita



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: JSP class loader

2006-07-25 Thread Christopher Schultz
Nikita,

 I read through your ClassLoader. It doesn't look like it will compile,
 
 Why? It were compiled and run on my PC.

Oh, sorry. The indentation was a little funny and I didn't see the
method signature for private byte loadClassData(File f). Never mind.

 I'm not sure what your ClassLoader does differently than any other
 ClassLoader; what have you added? If you haven't changed anything, then
 it's possible that your classloaders are not being GC'd:
 http://opensource2.atlassian.com/confluence/spring/pages/viewpage.action?
 pageId=2669
 
 As article says, container drops all reference to classloader during 
 web-app undeploy. This allows GC to remove classloader and free PermGen.
 In our system, JSP deployed inside web-app without web-app
 redeply. So references to ClassLoader aren't dropped.

Aah, I didn't realize that you were doing this. So, you basically
maintain your own versioning for each JSP? If I request that a JSP job
be run several times, each run gets its own class compiled and loaded?

This seems a little kludgey. You are you using JSP as a batch processing
platform?

 I see, threre are two possible ways for now: modify jsp servlet as I 
 going to before or create web-app for each business process and redeploy 
 it when new JSP arrived. 

I realize that you are probably required to work within the boundaries
of a pre-existing system, but I'm really curious to see why you are
using this platform to essentially perform batch processing.

-chris




signature.asc
Description: OpenPGP digital signature


Re: JSP class loader

2006-07-21 Thread Christopher Schultz
Nikita,

 I work on application which allows user to deploy/undeploy large number of
 the JSP pages to AppServer (JBoss 4.03sp1 + Tomcat 5.5). Standard Tomcat
 class loader caches classes for all deployed JSP internally and never clean
 its cache. This brings JVM to PermGen overflow error after several days of
 system work.

Ouch. Are you saying that the sheer number of classes in your system is
overflowing your memory? That doesn't seem likely.

After tomcat compiles your JSP, it loads the resulting class and
executes it like a servlet.

If you have an option enabled, it will detect updated JSPs, re-compile
them, and reload them. It is certainly possible that when this happens,
Tomcat discards the entire ClassLoader and starts fresh. In that case,
if you have 10,000 JSPs, then each time you reload, you'll get 10,000
more classes loaded into memory. If this happens enough times, you'll
run out of memory since Java does not clean up old, unused classes in
memory.

Is this the behavior you are describing? If so, then you can't fix the
problem by writing your own JSP compiler and/or ClassLoader. Your best
bet is not to modify your JSPs and have them re-loaded.

Is this in a development setting or production? I would say that having
JSP reloading turned on in production is a mistake.

-chris




signature.asc
Description: OpenPGP digital signature