Re: TomCat 6 performance issues

2009-12-24 Thread Elli Albek
Can you run a load test from another computer on the local network?
Something like apache AB gives a histogram and you should be able to
tell what percentage of your requests is the 5 seconds range. It is
best to run it directly to the tomcat private IP that is used inside
the local network, to make the path from the load test client to
tomcat as short as possible. That depends on your network
configuration, which varies among different colos and clouds.

If the loaded tomcat does not max the system resources (which can
happen if the application depends on an external app, like a
relational database or web service) you can even run AB on the same
machine and get close enough results, with the benefit of eliminating
potential network delays that may be a suspect.
Before you run the load test, do a wget or something like that from
the client machine to ensure that you are getting the correct
response. AB will also give you the size of the response, which you
can use to verify that the client actually gets correct responses from
tomcat.

If you have something fronting tomcat, you can run the load test once
to tomcat and again to the fronting application or load balancer. You
will get a general idea of latency of the different components.

E

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



Re: 2 Apache 1 Tomcat

2009-12-17 Thread Elli Albek
A note on reverse proxy:
request.getRemoteIP() will normally return the IP of the proxy and not
the IP of the client.
In Tomcat you will probably need to add a valve such as RemoteIPValve
(search this list) to fix the IP of the incoming request. Otherwise
your log files will show the IP of the proxy on all requests instead
of the IP of the client. Proxies add the IP of the caller as an HTTP
header.

For the log files you can avoid the valve by changing the log pattern
to log the HTTP header of the IP instead of the standard log patterns
(combined, common etc).  In that case you do not need the valve.

I still prefer the valve since it fixes the IP for the application
code as well as the log, so everything works normal.

We use reverse proxy instead of AJP since we put squid in front of
tomcat instead of apache. Depending on your requirements, I would
suggest looking into squid instead of apache, but expect a learning
curve.

E

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



Re: [OT] Context Chicken Egg Problem

2009-12-16 Thread Elli Albek
Another simple way to use tomcat with eclipse is to start tomcat with
remote debugging, and attach to it from eclipse. A couple of switches
in the tomcat startup script should do it.

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



Re: 2 Apache 1 Tomcat

2009-12-16 Thread Elli Albek
Or use apache as reverse HTTP proxy in front of Tomcat. In that case
tomcat is an HTTP server and there is nothing special to do (just
configure HTTP connector). You can put as many apache reverse proxies
as you need, tomcat configuration is agnostic to the proxies for the
most part. This will also give you the option of using other reverse
proxies in addition to apache.

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



Re: Very slow shutdown - 3 mins

2009-12-15 Thread Elli Albek
You have many threads that are not part of Tomcat, as Chuck mentions.
Whatever you start in the webapp you have to close as well. You can
close via a shutdown listener (Context listener), or if you use
something like Spring which already has built in shutdown hook,
implement their shutdown interface or register a callback.
When you shutdown a java executor (which can be seen in the thread
dump), notice that to be safe you can do a two steps shutdown. Step 1
does a graceful shutdown and waits. When the graceful shutdown times
out and the pool has not finishes, step 2, “hard” shutdown to finish
quickly. This will give you the benefit of finishing pending tasks and
limit the amount of time allowed before you kill the pool. A hard shut
down also means that tasks that are still waiting in the pool will not
be executed, so use with caution.

This also goes for everything that you create that potentially has
persistent resource usage, such as connection pools, HttpClient, etc.

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



Re: Char Encoding text streams on Tomcat 5.5 and Linux

2009-12-02 Thread Elli Albek
I was not replying to any post by you. I was replying to a post by a fellow
named Dan.

He states I have been successful using the charset filters on HTTP posts
and  XML

I am not sure I can respond to your comments since it seems that we talk
about different topics. In either case, why vent?

E

On Wed, Dec 2, 2009 at 8:17 AM, Christopher Schultz 
ch...@christopherschultz.net wrote:

 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 Elli,

 On 12/2/2009 2:40 AM, Elli Albek wrote:
  On your Linux box type “locale” + enter. The results should be UTF 8. If
 not
  change it.

 I can have my locale set to whatever I'd like, thank you very much.

  You can also set it in the file encoding java environment
  variable as suggested above as extra safety measure.

 Well, you can check it's value. By default, it's UTF-8 on my system (as
 mentioned in my post if you read the whole thing).

  Tomcat’s logic of determining the encoding from the request only applies
  when Tomcat is parsing text in the request.

 Tomcat's logic of determining the encoding for the request is mandated
 by the servlet spec and the HTTP spec. In this case, Tomcat /was/
 parsing text in the request: we are talking about POST data, here. Elli,
 please read the posts before replying.

  However if you read from the stream directly, using
 request.getInputStream()
  you are getting binary data. When you create java.io.Reader from that
 input
  stream you need to specify the encoding, or it will default to the file
  system encoding.

 Yes. If you look at the source code to Tomcat, you'll see that the
 encoding used comes from the request headers, or defaults to ISO-8859-1.
 I'm not going to repeat this again.

 If you create your own Reader (which you shouldn't be doing), you're on
 your own. In this case, nobody was creating their own Reader.

  The fact that tomcat is using ISO-8859-1 to read characters is not
 relevant
  if you are reading from the stream directly and use your own Reader to
  convert to characters.

 ..which I wasn't doing. Rather than repeatedly complaining about how you
 haven't read this thread properly, I'm simply going to stop.

  I am assuming this is a likely cause, since the XML
  parsing succeeds

 Okay, I can't help myself: when did we start talking about XML?

 - -chris
 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.10 (MingW32)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

 iEYEARECAAYFAksWkwEACgkQ9CaO5/Lv0PCI1QCgkC9SPmdWkHDPiLmEqE9l3xGm
 ASIAoLViW6EMWL67yVxBfMEJDXj9utR4
 =R438
 -END PGP SIGNATURE-

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




Re: Char Encoding text streams on Tomcat 5.5 and Linux

2009-12-01 Thread Elli Albek
Hi,

On your Linux box type “locale” + enter. The results should be UTF 8. If not
change it. You can also set it in the file encoding java environment
variable as suggested above as extra safety measure.

Tomcat’s logic of determining the encoding from the request only applies
when Tomcat is parsing text in the request.

However if you read from the stream directly, using request.getInputStream()
you are getting binary data. When you create java.io.Reader from that input
stream you need to specify the encoding, or it will default to the file
system encoding. In that case the reader is a java API that does not go
through the tomcat APIs. This reader has no knowledge of the request data,
any encoding specified in it or what tomcat will default to.

The fact that tomcat is using ISO-8859-1 to read characters is not relevant
if you are reading from the stream directly and use your own Reader to
convert to characters. I am assuming this is a likely cause, since the XML
parsing succeeds, so I assume the XML parser is getting raw bytes from
tomcat rather than characters (using request.getInputStream() as opposed to
request.getReader()).

In that case the XML parser will resolve the encoding by itself. Ideally
when you create your own reader for plain text you can use the character set
in the request, however if you do not trust the clients just force UTF-8 for
the OS and the tomcat process by specifying the OS locale. You can also
force UTF8 encoding when you create the reader in your java code (it is a
constructor parameter for the reader), but it is looks easier to just
specify it in the OS/tomcat start up without changing the application code.

E


Re: Java Out of Heap Issue

2009-11-18 Thread Elli Albek
I consider old code part of application code :) no age discrimination
when it comes to memory leaks.

 What you describe in your memory graph is a simple memory leak.
 Generally, I would look in that order:

  1a. Old code? Look for improperly closed DB connections.

 1.      Sessions
 2.      Application code
 3.      Other webapps

 p

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



Re: Possible to do async processing?

2009-11-16 Thread Elli Albek
Hi,
The advices given above are good. If you make this job triggered by a
servlet, then an attacker can use it to easily bring down your system
with excessive load.

You also have problems of clean shutdown. The thread pool that you
start needs to have blocking shutdown with some context listener, to
make sure that all jobs are finished when you undeploy or shut down
the server. This is not hard to do, but you should test it by making
sure a job finishes when you shut down. Just add a slow job that, and
kill the server.

Slow job:
public void run(){
System.out.println(Starting slow job);
try{
  Thread.sleep(6); // 1 min
}catch(Throwable e){
  e.printStachTrace();// possible kill, watch out for this
}
System.out.println(Finished slow job);
}

Add this job to the pool, shut down the server, and look at the logs
for the messages. You should also see the server hanging until the job
is completed.

A simpler option would be to write a java class with a main method,
and run it from cron. We have a bunch of those. Not dependent on
tomcat, no security problems. You can have many tomcats with the same
configuration, something that would be more difficult with a scheduler
that is part of your app.

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



Re: Some advice on apache tomcat

2009-11-16 Thread Elli Albek
You can also look at squid to serve static files and load balance. So
squid fronts tomcat and your other apps. Squid can serve your static
files as well. All you have to do it make sure your static files
return a cache header like max-age, and squid will serve them without
going to the origin (tomcat). Squid can also load balance tomcats and
route requests for multiple origins based on some rules. We have squid
doing virtual hosting of tomcats that run different apps, as well as
serving static content and caching dynamic content.

The down sides vs apache:
1. Not as many plugins and options
2. The configuration rules are simpler and more widely
known/understood in apache
3. Hard to rewrite URLs. Not impossible, but mod rewrite is much much
easier to deal with. Actually any manipulation of the request/response
is less than trivial on squid.

If you go for squid, 2.7 and above. Earlier versions are not as good
for reverse proxing.

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



Re: Java Out of Heap Issue

2009-11-16 Thread Elli Albek
You can try getting an object dump from a profiler and see which
objects are the source of memory starvation. Simple JSPs are very
unlikely to cause memory starvation, but you mentioned “application
code”, which implies that you have more than simple JSPs.

A few things you want to cross off your performance check list, which
will not solve your problem, but are generally necessary:
1. JVM -server option, just in case
2. Disable session persistence
3. If you application does not use sessions, disable them for all JSPs
(typical place to do it is header JSP include)
4. Force session termination, no long running sessions.
5. Remove all apps that you do not need. Tomcat comes with a few built
in apps and those are not trivial to find. Make sure conf/Catalina and
all its sub directories contain only apps that you need. Host manager
and such should be deleted. Same with war files.

What you describe in your memory graph is a simple memory leak.
Generally, I would look in that order:
1.  Sessions
2.  Application code
3.  Other webapps

1 and 3 are easy to deal with. If you don’t need sessions make sure
they are not created at all. If you do, force session termination
after a few minutes in master web.xml or other XML files. Notice that
one file can define a value and another can overwrite it, so you have
to make sure all are checked.

If that does not work, application code is the next candidate. You can
start with an object dump with a profiler or a simple code review/step
through in a debugger.

E

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



Re: Regarding 1 Webserver Multiple Web App project

2009-11-14 Thread Elli Albek
Tomcat by itself as a web server can do that without too much
complexity. If you use something in front of it, then that something
need to know which domains go to tomcat as well.

You don't necessarily need to front tomcat with apache/AJP. You can
have tomcat be the web server as well, or front it with any HTTP
reverse proxy such as squid.

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



Re: Memory, handles and threads increasing in Tomcat 5.5

2009-11-13 Thread Elli Albek
Hi,

Without knowing what your application is doing, here is something you should
look at:

External dependencies.

If your application is stable performance wise at steady state for a few
thousands of GC cycles, and then jumps in resources out of nowhere, it is
very possible that this is due to an external interruption.

Possible interruptions:

   1. Another process that runs on the machine of the tomcat server. Cron
   job, log file compression, you name it. Go over the process list and cron to
   start with. We run performance tests only on very clean machines, bare bones
   linux with java and tomcat and nothing else.
   2. If your app is using an external application, like a relational
   database, web service, other HTTP server, email system, that system may be
   the periodic bottleneck. If it has a periodic interruption (like a job that
   runs on that machine, or just its own behavior under constant load), it may
   block your threads for a short amount of time, causing the thread count to
   increase.
   3. Something that runs periodically inside your application. Same as
   above, but not external. This may also be a third party library that you use
   in your app without directly doing it yourself.
   4. Get rid of all webapps that are not the web app that you test. There
   are a few that come with tomcat by default. Make sure your tomcat runs only
   the app you are testing. Conf/Catalina and all its subdirectories should
   contain one xml file at most if you need context files. All your web app
   directories together should contain one war file/directory combined.
   5. If your system actually consists of a few war files, load test each
   one of them separately to find the trouble maker. When you test one, the
   others should not be installed on tomcat (IE, delete the war file and its
   sibling directory). Not installed and not running, NOT INSTALLED. Big
   difference.

Try to do a thread dump while the jump is happening, if you can catch that.
If you can get a thread dump while the number of the threads increasing
(sounds like difficult timing from what you describe) you will see what the
threads are doing at that point, and at least one of thread will be able to
give you an insight why they cannot handle the current momentary load.

That is quite a coincidence that as we speak I am dong exactly that, load
testing tomcat on different EC2 combinations :)

E


Re: Tomcat 6 encoding issue

2009-11-12 Thread Elli Albek
You can try forcing the JVM to start with UTF 8 using a JVM parameter.
-Dfile.encoding=UTF-8
Where you put it depends on how you start tomcat, I think JAVA_OPTS will do it.

This is quick and may work. You can also try to force the servlet
output stream to be in the encoding that you want from your code
before you do any writing. If you are writing the text from a servlet,
its a function of the response. If you are doing it in JSP, it is a
parameter of the JSP page.
%...@page pageEncoding=UTF-8%
You must define the encoding on the output stream before you start writing.

We have a warning in one of our startup classes, so we know about
those problems when they happen (in this case its in filter init, can
be pretty much anywhere)

String defaultCharset = Charset.defaultCharset().name();
if (!defaultCharset.substring(0, 3).equalsIgnoreCase(utf)) {
// not UTF!
logger.warn(JVM Character encoding is not UTF, it is ' +
defaultCharset + ');
}

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



Re: [OT] WebappClassLoader and undeploy

2009-11-11 Thread Elli Albek
Tomcat 5.5 version + log message when executed:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the License); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.catalina.core;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.imageio.ImageIO;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;

/**
 * Provide a workaround for known places where the Java Runtime environment can
 * cause a memory leak or lock files.
 * p
 * Memory leaks occur when JRE code uses
 * the context class loader to load a singleton as this will cause a memory leak
 * if a web application class loader happens to be the context class loader at
 * the time. The work-around is to initialise these singletons when Tomcat's
 * common class loader is the context class loader.
 * p
 * Locked usually files occur when a resource inside a JAR is accessed without
 * first disabling Jar URL connection caching. The workaround is to disable this
 * caching by default.
 */
public class JreMemoryLeakPreventionListener implements LifecycleListener {

protected static final Log log =
LogFactory.getLog(JreMemoryLeakPreventionListener.class);
protected static final StringManager sm =
StringManager.getManager(Constants.Package);

/**
 * Protect against the memory leak caused when the first call to
 * codesun.awt.AppContext.getAppContext()/code is triggered by a web
 * application. Defaults to codetrue/code.
 */
protected boolean appContextProtection = true;
public boolean isAppContextProtection() { return appContextProtection; }
public void setAppContextProtection(boolean appContextProtection) {
this.appContextProtection = appContextProtection;
}

/**
 * Protect against resources being read for JAR files and, as a side-effect,
 * the JAR file becoming locked. Note this disables caching for all
 * {...@link URLConnection}s, regardless of type. Defaults to
 * codetrue/code.
 */
protected boolean urlCacheProtection = true;
public boolean isUrlCacheProtection() { return urlCacheProtection; }
public void setUrlCacheProtection(boolean urlCacheProtection) {
this.urlCacheProtection = urlCacheProtection;
}

public void lifecycleEvent(LifecycleEvent event) {
// Initialise these classes when Tomcat starts
if (Lifecycle.INIT_EVENT.equals(event.getType())) {
log.info(Running JreMemoryLeakPreventionListener
(appContextProtection=
+ appContextProtection + , 
urlCacheProtection= +
urlCacheProtection + ')');
/*
 * Several components end up calling:
 * sun.awt.AppContext.getAppContext()
 *
 * Those libraries / components known to trigger memory leaks due to
 * eventual calls to getAppContext() are:
 * - Google Web Toolkit via its use of javax.imageio
 * - Tomcat via its use of java.beans.Introspector.flushCaches() in
 *   1.6.0_15 onwards
 * - others TBD
 */

// Trigger a call to sun.awt.AppContext.getAppContext(). This will
// pin the common class loader in memory but that shouldn't be an
// issue.
if (appContextProtection) {
ImageIO.getCacheDirectory();
}

/*
 * Several components end up opening JarURLConnections without first
 * disabling caching. This effectively locks the file. Whilst more
 * noticeable and harder to ignore on Windows, it affects all
 * operating systems.
 *
 * Those libraries/components known to trigger this issue include:
 * - log4j versions 1.2.15 and earlier
 * - javax.xml.bind.JAXBContext.newInstance()
 */

// Set the default URL caching policy to not to cache
if (urlCacheProtection) {
try {
// 

Re: [OT] WebappClassLoader and undeploy

2009-11-11 Thread Elli Albek
Actually Mark can you take a quick look at the class I sent and see if
it makes sense. I swapped juli with commons logging (which is in bin)
but now I am not sure this is necessary, this library may already be
loaded regardless of this filter.

E

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



Re: Tomcat 6 encoding issue

2009-11-11 Thread Elli Albek
Which library are you using to get the external page? java.net? HttpClient?

What do you do with the page that you download? It looks from the
exception that you are writing it to the servlet IO, is that the case?

Are both of your tomcats running on the same JVM version?

E

On Wed, Nov 11, 2009 at 8:10 PM, pramodpm pramod_me...@satyam.com wrote:

 We are facing an encoding issue in apache-tomcat-6.0.20. This is working in
 tomcat 5.5.23.  We are trying to  make a get request to external site. The
 page contains some utf-8 characters.  When we access the page from the
 application we are getting the following error.
 Can you please help us to resolve this issue. Any help is appreciated.




 WARNING: Handler caused Not an ISO 8859-1 character: 83


 java.io.CharConversionException: Not an ISO 8859-1 character: 83

 at javax.servlet.ServletOutputStream.print(ServletOutputStream.java:89)

 at

 at java.io.OutputStream.write(OutputStream.java:99)


 --
 View this message in context: 
 http://old.nabble.com/Tomcat-6-encoding-issue-tp26313150p26313150.html
 Sent from the Tomcat - User mailing list archive at Nabble.com.


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



Re: [OT] WebappClassLoader and undeploy

2009-11-10 Thread Elli Albek
Sorry Mark.

Well this class loading scheme (context class loader - static
variable) sounds little like a bug.

Thanks for that startup class. I think it will solve a problem that we
have (using imageio). So you just add it as high up as possible in the
server.xml hierarchy?

E

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



Re: WebappClassLoader and undeploy

2009-11-09 Thread Elli Albek
Managing class loaders is done in the JVM. Tomcat cannot force the JVM
to garbage collect class loaders, in the same way that it cannot force
the JVM to garbage collect any object.
If the class loader is unreachable, and all other objects that this
class loader provided are also unreachable, then the JVM can garbage
collect it like any other object.

This garbage collection is heavier than simple object reference. I
assume the JVM will do it only in major garbage collections and maybe
even not in every major one. If your test app is not doing anything,
there is no reason for the JVM to actually do something about it since
memory is not consumed. If you try to force major garbage collections,
eventually it should happen. If you run a load test, which will force
tomcat to consume memory, then you will eventually get to a major
garbage collection. This can take much longer than what you would
think. If the code is simple (like JSP page and hello world type of
servlet) it can be optimized by the JVM to consume memory on a local
stack based heap (per thread), and not use the JVM main heaps.

If you keep a reference to one object that was created from this class
loader, then the Class object of this object is reachable, and the
class loader is reachable via the Class. Since it is reachable, it
cannot be garbage collected.

WebappLoader is a class that has the code to manage a webapp
lifecycle. It is not a class loader. The JVM to track references to it
like any other simple object (String). In addition, it is an internal
tomcat object, so it is a lot simpler to keep track of references to
it in the tomcat code. It is not visible to the webapps or exposed to
user code that can leak it.

WebappClassLoader is the opposite: It is a real class loader. Garbage
collecting it is not a simple matter. My guess is that:

1.  If you constantly load the memory, then eventually it will be
garbage collected.
2.  If it is not garbage collected in that case, there is a reference
leak, something is keeping a reference to either the class loader or
to an object that was loaded by from it.

Tomcat is releasing references to objects on its side, but the user
code can do other things.

If the web app contains one servlet and one JSP page, that should be
easy to follow. Tomcat keeps references to those objects (both should
be servlets), but also releases them when you redeploy. You can verify
that the objects are gone. The actual instances should be gone very
quickly since they are simple objects. JSP page is turned into a
class, you should see it in the memory management tool.

Notice that if the web app is reloaded, the new class loader will load
the same classes again, so they will have the same class name, but
they will have separate Class instances. You will have two objects
that have the same class name, but are different class.

Other possible reference leaks from the webapp to the outside:
Threads that are left running
JNDI
Sessions
Thread local
Any library in a class loader above the webapp (in class loaders app,
system, common and shared, possibly even in Catalina but less likely)
Logging and reflection libraries always star as favorite leakers.

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



Re: WebappClassLoader and undeploy

2009-11-09 Thread Elli Albek
Thomas, what is the issue with javax.imageio? Do they really use
context class loader for loading static variables?

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



Re: [OT] ConnectionPool question

2009-11-07 Thread Elli Albek
Chris, as long as we are having fun its all good. I think this
question is something many developers ask. I have seen it here and in
other forums.

You are correct, everything is wrapped. The connection wrapper spawns
statment wrappers which spawn result set wrappers, and everything is
tracked in parent child relationships.

E

On Fri, Nov 6, 2009 at 5:54 PM, Christopher Schultz
ch...@christopherschultz.net wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 Elli,

 Okay, I think we've hijacked Josh's thread enough to at least mark it as
 off topic. :)

 On 11/5/2009 10:37 PM, Elli Albek wrote:
 Christopher Schultz wrote:
 Pooled connections are almost certainly not behaving this way. This has
 been discussed at least twice in the last week or two, and, I believe,
 already once in this thread.

 This is certainly not the case for my DBCP library (1.2.2). I just
 stepped through the source code: Calling connection.close() is closing
 result sets and statements.

 I'm not sure how calling Connection.close (where the Connection object
 is one from DBCP) would possibly be able to close ResultSet and
 Statement objects created by the underlying connection.

 Unless, I suppose, they decided to wrap /everything/ and register all
 the ResultSet and Statement objects handed-out by the underlying
 Connection for the purposes of (possibly) closing them later. I should
 really read the source :)

 Below is the DBCP code that keeps track of open statements/result sets
 and closes them when the connection is closed (BDCP 1.2.2).

 Yup: it looks like they do wrap/register everything and then close it
 for you. It's nice that they followed the spec, here :)

 - -chris

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



Re: SEVERE: All threads (700) are currently busy, waiting. Increase maxThreads (700) or check the servlet status

2009-11-06 Thread Elli Albek
As Charles suggested, you need a thread dump. There is too much
complexity in your setup to be able to find your problem without
actually inspecting the machine, but a thread dump can take you right
to the source of the problem in a matter of minutes.

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



Re: ConnectionPool question

2009-11-05 Thread Elli Albek
Hi,

 Elli,

 On 11/4/2009 7:01 PM, Elli Albek wrote:
 I also
 remember that closing a connection closes statements and result sets, but it
 has been a while since I read the source.

 Pooled connections are almost certainly not behaving this way. This has
 been discussed at least twice in the last week or two, and, I believe,
 already once in this thread.

 - -chris

This is certainly not the case for my DBCP library (1.2.2). I just
stepped through the source code: Calling connection.close() is closing
result sets and statements. In addition I commented the code that
closes statements and result sets in our framework to create a leak,
and DBCP closed everything. Relevant DBCP Code snippets below.

Josh:
You are correct, wrapping connections, statements and datasources is
not a good idea. It is complicated code and can lead to many problems.
Fortunately for you, you don’t have to do that. You can recklessly
leave statements and result sets open, and as long as you call
connectiohn.close() at the end DBCP will do all the work for you. You
can verify this by downloading the source code, and putting a break
point just before you call close.

I am telling you this based on experience. We do wrap everything for
logging purpose (data source, connection, statement). Doing it was far
from trivial, even using the DBCP ready-to-use wrapper classes
(DelegatingConnection, DelagatingStatement…).

Of course is it good to follow best practices and close things as soon
as possible in finally blocks. But in your case, it may just be an
unnecessary intermediary step that you can skip. Maybe you can start
with a brute force filter and rely on the good fellows that wrote DBCP
to clean up the mess. Then go to a better solution, where you use a
framework that does most of this work for you. There are too many java
database frameworks to list, some of them are heavy, some are minimal
right above the JDBC layer, and still provide automatic closing of
resources.

Below is the DBCP code that keeps track of open statements/result sets
and closes them when the connection is closed (BDCP 1.2.2).

PollableConnectionFactory:
public void passivateObject(Object obj) throws Exception {
  ...
  if(obj instanceof DelegatingConnection) {
((DelegatingConnection)obj).passivate();
  }
}

DelegatingConnection (called via subclass PollableConnection):

protected void passivate() throws SQLException {
try {
// The JDBC spec requires that a Connection close any open
// Statement's when it is closed.
List statements = getTrace();
if( statements != null) {
Statement[] set = new Statement[statements.size()];
statements.toArray(set);
for (int i = 0; i  set.length; i++) {
set[i].close();
}
clearTrace();
}
setLastUsed(0);
if(_conn instanceof DelegatingConnection) {
((DelegatingConnection)_conn).passivate();
}
}
finally {
_closed = true;
}
}

Delegating statement:
public void close() throws SQLException {
try {
try {
if (_conn != null) {
_conn.removeTrace(this);
_conn = null;
}

// The JDBC spec requires that a statment close any open
// ResultSet's when it is closed.
// FIXME The PreparedStatement we're wrapping should
handle this for us.
// See bug 17301 for what could happen when ResultSets
are closed twice.
List resultSets = getTrace();
if( resultSets != null) {
ResultSet[] set = (ResultSet[])
resultSets.toArray(new ResultSet[resultSets.size()]);
for (int i = 0; i  set.length; i++) {
set[i].close();
}
clearTrace();
}

_stmt.close();
}
catch (SQLException e) {
handleException(e);
}
}
finally {
_closed = true;
}
}

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



Re: ConnectionPool question

2009-11-04 Thread Elli Albek
As far as I remember, abandoned is a connection that was not closed. So if
you call recycle on a connection it will not generate abandoned message. The
messages that you see are from connections that you do not close. I also
remember that closing a connection closes statements and result sets, but it
has been a while since I read the source.

Give the filter above a shot. It would takes maybe an hour to get running
and can solve all your problems in one go. You may experience a major boost
to your system performance even comparing to closing every connection
(because you will be using a single connection per request as opposed to
multiple open/close).

E

On Wed, Nov 4, 2009 at 11:43 AM, Christopher Schultz 
ch...@christopherschultz.net wrote:

 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 Josh,

 On 11/4/2009 12:11 PM, Josh Gooding wrote:
  type=javax.sql.DataSource

 [snip]

  res-typejavax.sql.DataSource/res-type

 I believe it is these types that must match, and they do. Don't change a
 thing.

 - -chris
 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.10 (MingW32)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

 iEYEARECAAYFAkrx2VUACgkQ9CaO5/Lv0PCvIQCgvuD2fkIQ7iHH+xlT22SdRmnq
 E7YAn0JmNbP22/rm6hwKPchNm1dbbXyj
 =zIOM
 -END PGP SIGNATURE-

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




Re: Tomcat and PermGen

2009-11-03 Thread Elli Albek
Thanks for this link. Reading that page made me a little pessimistic.

E

On Mon, Nov 2, 2009 at 9:38 PM, Caldarale, Charles R 
chuck.caldar...@unisys.com wrote:

  From: Gerwood Stewart [mailto:gstew...@une.edu.au]
  Subject: RE: Tomcat and PermGen
 
  Do you know of any ways to track down what might be 'stuck' here or a
  starting point I could use?

 Take a look at this, although the thread you read probably covered much of
 it:

 http://opensource.atlassian.com/confluence/spring/pages/viewpage.action?pageId=2669

 You're most likely going to have to slog through heap profiler output
 looking for objects (including java.lang.Class instances) that belong to the
 stopped webapp.  They'll show up more readily if you just undeploy, not
 redeploy.

  - Chuck



Re: ConnectionPool question

2009-11-03 Thread Elli Albek
No, you do not need to close the XXXMetaData classes.

E

On Tue, Nov 3, 2009 at 12:02 PM, Josh Gooding josh.good...@gmail.comwrote:

 One more question on bleeding resources.  When closing RS / statement /
 connections.  Do I have to do anything with the MetaData if I got that as
 well?  (I.E Do I explicitly have to close the metadata as well?)

 Josh

 On Tue, Nov 3, 2009 at 2:01 PM, Josh Gooding josh.good...@gmail.com
 wrote:

  Elle,
 
  I am going to dig into this code and check it out.  I want to know more
  about how to use threadlocal and filters.  (Sorry I'm not as experienced
 in
  Tomcat as some for you gurus here).
 
  The code looks promising and I like the 2nd option due to the fact that
  each HTTP req. only has one connection (which should drop the overhead
  immensely) however for right now, I just want to fix the bleeding issue
  (which it seems that I have caught a good portion of them), so I'll use
 my
  legacy code, but during a minor code release, I can definitely look
 into
  rolling this out.  I am getting a ton of abandoned connection warnings
 in
  the console window, so I need to find out where these are coming from
 now.
 
  I don't know where to begin thanking you guys but thank you.  I've gotten
  more mentoring here on this listing than I have in 2 years at my current
  employer.  Thank you all again.
 
  - Josh
 
 
  On Mon, Nov 2, 2009 at 3:40 PM, Christopher Schultz 
  ch...@christopherschultz.net wrote:
 
  -BEGIN PGP SIGNED MESSAGE-
  Hash: SHA1
 
  Elli,
 
  On 11/2/2009 4:08 AM, Elli Albek wrote:
   I think you can have a solution without changing your code.
  
   Try something like this:
  
   getConnection() static method should get the connection, and add it to
 a
   list that you keep in threadlocal.
  
   recycleConnection() should close the connection and remove the
  connection
   object from thread local.
  
   Add a servlet filter that closes all connections in thread local. The
  filter
   calls next filter, and in a finally block get the connections from
  thread
   local, close all of them, and clear the list in thread local.
 
  This is a horrible, nasty hack and it's entirely brilliant!
 
  I would change Elli's implementation just slightly, and actually write
  your own DataSource implementation that piggybacks on another one.
  Basically, you just wrap the DataSource that Tomcat provides either by:
 
  a. Using JNDI to look-up the Tomcat-created JNDI DataSource and just
writing the plumbing code to pass everything through
  b. Actually subclass the DataSource class(es) provided by Tomcat and
use /those/ in your Resource configuration.
 
  I would also not make any of this static... there's just no reason to do
  so, especially if your DataSource object is in the JNDI context.
 
  Although the /real/ solution is to fix the code, I really like this
  solution for a couple of reasons:
 
  1. It requires no wrapping of Connection, Statement, etc. objects
(which is entirely miserable if you've ever had to do it)
  2. It requires no changes to your code whatsoever (if you use my
DataSource-wrapping suggestion above)
  3. You won't end up closing your connection, statement, result set, etc.
too early because your code has completed execution (unless you
are using JDBC resources across requests, which is another story)
 
  What this won't help, unfortunately is:
 
  * Closing your ResultSet and Statement objects (though this can be
   solved by wrapping the Connection, Statement, etc. objects handed-
   out by your DataSource. Yes, it's miserable.)
 
   This will allow you to keep your legacy code. As far as I remember
 DBCP
  has
   an option to close the result sets and statements when you close the
   connection. If not this will partly work.
 
  I don't believe commons-dbcp has this capability at all. I'm willing to
  read any documentation to the contrary, though.
 
   Version 2: Advanced
  
   Keep the actual connection in thread local. You will have one
 connection
  per
   HTTP request. getConnection() should be something like
  
   public static /* NOT synchronized */ Connection getConnection(){
  
   Connection c = ...// get the connection from thread local
  
   if (c != null)
  
   return c;
  
   Connection c = ...// get the connection from JNDI/DBCP
  
   // put connection in thread local
  
   return c;
  
   }
 
  I like this technique, too. You just have to decide if it's acceptable
  for your webapp to re-use connections. I can't imagine why that would be
  a problem, but it's worth considering before you blindly do it. This
  optimization can save you from deadlock (though you're killing-off
  connections after 15 seconds anyway) and should significantly improve
  the performance of your webapp because you won't be bleeding so many
  connections: you're limited to bleeding one connection per request
  instead of potentially dozens.
 
   recycleConnection(){
  
   // empty, connection will be recycled by filter

Re: ConnectionPool question

2009-11-02 Thread Elli Albek
Here is some idea for you:

First, you have two static methods to get and return the connection inside a
listener class. Those methods do not have anything to do with the listener
(which is an instance), and also and also do not need synchronization.
Synchronizing on getConnection can be a big bottleneck, especially if you
are doing a validation query onBorrow. Having said that, it sounds like this
is the least of your problems now.

I think you can have a solution without changing your code.

Try something like this:

getConnection() static method should get the connection, and add it to a
list that you keep in threadlocal.

recycleConnection() should close the connection and remove the connection
object from thread local.

Add a servlet filter that closes all connections in thread local. The filter
calls next filter, and in a finally block get the connections from thread
local, close all of them, and clear the list in thread local.


This will allow you to keep your legacy code. As far as I remember DBCP has
an option to close the result sets and statements when you close the
connection. If not this will partly work.


This is as close as you can get to having the connections reclaimed
immediately without rewriting your application.


Something like:

public static /* NOT synchronized */ Connection getConnection(){

Connection c = ...// get the connection from JNDI/DBCP

ListConnection connections = // get or create from thread local

if(connections.contains(c) == false)

// make sure c.equals() works as object reference equality, eg ==

// You may have to read DBCP code for this or add a break point and trace
through the code until you get to equals()

connections.add(c);

if(myLogger.isDebug())

myLogger.debug(“Request consumed “+ list.size() + “ connection(s)”);

return c;

}


public void doFilter(ServletRequest req, ServletResponse res, FilterChain
chain) throws IOException, ServletException {

try{

// handle request

chain.doFilter(req, res);

}finally{

ListConnection connections = ...// get from thread local

if (connections != null){

for(Connection c: connections){

try{

c.close();

}catch(Throwable t){

myLogger.error(“Error on connection close”, t);

}

}

connections.clear();

}

}

}


public static synchronized void recycleConnection(Connection c) {

ListConnection connections = ...// get from thread local

connections.remove(c);

try {

c.close();

} catch (Throwable t) {

// DO NOT eat the exception, especially when there are known issues in the
connection management code

myLogger.warn(“Error closing connection”, t);

}

}


I also think that I have seen somewhere a configuration that does the above
for you, but if not its not a lot of code to do yourself. Map the filter to
all the URL mappings that can possibly can open connection, which in the
worse case is /*.


Notice that with the code sample you wrote, a typical application will
consume many connections for one request (possible one per statement), and
worse than that, will not be able to perform transactional writes (since
each write is on a separate connection).


Version 2: Advanced

Keep the actual connection in thread local. You will have one connection per
HTTP request. getConnection() should be something like


public static /* NOT synchronized */ Connection getConnection(){

Connection c = ...// get the connection from thread local

if (c != null)

return c;

Connection c = ...// get the connection from JNDI/DBCP

// put connection in thread local

return c;

}


recycleConnection(){

// empty, connection will be recycled by filter.

}

public void doFilter(ServletRequest req, ServletResponse res, FilterChain
chain) throws IOException, ServletException {

try{

// handle request

chain.doFilter(req, res);

}finally{

ListConnection connections = ...// get from thread local

if (connections != null){

for(Connection c: connections){

try{

c.close();

}catch(Throwable t){

myLogger.error(“Error on connection
close”, t);

}

}

connections.clear();

}

}

}

public void doFilter(ServletRequest req, ServletResponse res, FilterChain
chain) throws IOException, ServletException {

try{

// handle request

chain.doFilter(req, res);

}finally{

Connection c = ...// get and REMOVE from thread local

if (c != null){

try{

c.close();

}catch(Throwable t){

myLogger.error(“Error on connection close”, t);

}

}

}

}


The filter is the same, but not using lists. Version 2 will give you one
connection per servlet request, which normally I would not do for a well
written DAO code, but in your case you are not really dealing with such
code. You can get large performance boost by having one 

Re: ConnectionPool question

2009-11-02 Thread Elli Albek
Oops, I had a copy paste error. Version 2 has the filter method twice.
Ignore the first, use the second. Notice this code was written in an email
client, not an IDE :)

E


Re: starting tomcat from ant not working

2009-11-02 Thread Elli Albek
Hi,
This is how we start tomcat from ant. ${server} is your tomcat installation
directory. Then we have a condition on a URL, so we know tomcat actually
starts and handling HTTP requests.

java jar=${server}/bin/bootstrap.jar fork=true spawn=true
dir=${server}/bin
jvmarg value=-Dcatalina.home=${server} /
arg line=start /
 /java

Notice the startup folder and catalina home argument. This is to avoid
conflicts with other tomcat installations that may be on the system.

E

On Sun, Nov 1, 2009 at 9:16 PM, Dean Hiller d...@alvazan.com wrote:

 I have tried from ant and programmed up a main class to start tomcat via
 catalina.bat start and tried catalina.bat start from ant as well.
 Lastly, I finally tried directly running the exact command that
 catalina.bat
 start tries to run and then ended up with classnotfound which makes no
 sense
 since I thought the bootstrap class is supposed to put that
 together.(any ideas?)




Re: [OT] Hammers and nails (was Re: A question about log-rotation on catalina.out)

2009-11-02 Thread Elli Albek
How did this make it into the tomcat users list? :)

CPAN: Driven by users. Java (JCP) Driven by vendors.


Re: Tomcat Memory and Garbage Collection questions...

2009-11-02 Thread Elli Albek
A question:

Do you guys use hot deployment of applications? If you do *not*, then
Joseph’s tips are the first things to look at, in short it is the
application code keeping too many references.

If you do hot deployment, then the number of possibilities goes up
significantly. Now you are also talking about references to class loaders
and memory cleanup at shutdown, which is another topic altogether.
E

On Mon, Nov 2, 2009 at 1:44 PM, Joseph Morgan joseph.mor...@ignitesales.com
 wrote:

 I hope Mr. Caldarale answered your question, because you may otherwise
 be looking at the 800lb Gorilla in the room.

 Memory problems within Tomcat could be a number of very hard to see
 things, but some quick candidates are:

 * Programmers caching too much data from the DB (or file system) into
 context attributes
 * Programmers using context attributes to store session data
 * Programmers pushing too much data into session attributes
 * Session timeout is set too high and sessions aren't timing out


Re: DBCP woes (running out of cursors).

2009-10-28 Thread Elli Albek
Hi,
From what I can remember, which has been a long time ago, requests are
being handled by servlets after the shutdown process has started and
the pool was closed. I would imagine that this is a violation of the
spec as well, but I am not sure. You would imagine that JNDI resources
should be available for the web app until it is closed, as well as
during the shutdown process. Context listeners should be able to
access the pool via JNDI even during shutdown.

The problem with about to be shut down is that it is not fully shut
down. It is not shut down at least in the sense that the context
listener is running. There may be another listener that tries to use
the database for flushing asynch writes. So I rather keep connection
management outside of the app. Thats why the tomcat listener seems
like a better choice, especially when there is a dedicated event for
after stop.

From the testing, after stop is truly the last event in the chain and
runs after the web app is completely shut down and all its internal
listeners are called. In other words, objects that are started outside
the app should not be shut in from within the app if possible. The web
app should only stop what it starts by itself.

E

On 10/28/09, Christopher Schultz ch...@christopherschultz.net wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 Elli,

 On 10/28/2009 12:21 AM, Elli Albek wrote:
 In terms of listeners, I saw that Tomcat executes requests while in
 the closing process.

 That's a problem. What kind of listener are you using?

 My understanding was that:

 1. Tomcat does not remove the connection pool
 2. Once the shutdown process has started, no new requests will be
 handled by the currently-shutting-down context

 Could these two items give the result you are observing? It's easy
 enough to have your webapp close the DataSource (even though it's kinda
 stupid that Tomcat doesn't do it for you).

 That depends on which shutdown it is. Understanding 2 is not correct
 from my debugging. You can have a sequence of:
 1. Connection pool closed
 2. Request sent to servlet

 The documentation for ServletContextListener.contextDestroyed says:

 
 Notification that the servlet context is about to be shut down. All
 servlets and filters have been destroy()ed before any
 ServletContextListeners are notified of context destruction.
 

 Assuming that servlets aren't being re-initialized to service new
 requests, using a ServletContextListener ought to work in this case. I'm
 happy to hear an explanation for why my assumption isn't true, but this
 woul dbe my expectation. If your webapp is handling requests after the
 ServletContextListener.contextDestroyed method is called, I would
 consider that a violation of the servlet specification.

 If you want to add a listener that closes the pool, I would try
 adding tomcat lifecycle listener to the context. You can handle
 event Lifecycle.AFTER_STOP_EVENT. Try both listeners (web app and
 tomcat) and see which one runs last, and put the code there.

 I'm guessing that Tomcat's listener would execute after the
 ServletContextListener, since AFTER_STOP_EVENT indicates that the stop
 has occurred, while the servlet-API listener says it is about to be
 shut down.

 Then the vision of J2EE designers of separation of roles
 materializes :)

 Something tells me those guys didn't exactly invent the concept of
 separation of roles.

 - -chris
 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.10 (MingW32)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

 iEYEARECAAYFAkrodboACgkQ9CaO5/Lv0PAhGQCgooVyE8753TIz635X2lSvZJOV
 j8cAoJnX6kDBSuBscVlwjEX0kZ5SlAun
 =u9j7
 -END PGP SIGNATURE-

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



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



Re: DBCP woes (running out of cursors).

2009-10-27 Thread Elli Albek
Thanks for your replies. I agree that Tomcat should be responsible for
all objects that are configured in Tomcat, and the web app should be
responsible for objects that are created by the webapp. Currently it
does not happen properly in tomcat. This is not related to DBCP code,
it is all Tomcat code.

In terms of listeners, I saw that Tomcat executes requests while in
the closing process. This may mean that after the context listener
closed the pool, a new request will cause it to initialize again. We
had a similar problem of things being created after shutdown started,
and there are many permutations of listeners and sequences to test.
Lots of debugging to do here. This again is irrespective of the
listener which I am sure is closing the connection pool, it is a
tomcat lifecycle issue.

 It is built into Tomcat. Just read the docs for JDBC DataSources:
 http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html

I am talking about something else. Basically the XML is short:

GlobalNamingResources
Resource auth=Container

type=javax.sql.DataSource
propertiesFile=database_pool_configuration_file.properties /
/GlobalNamingResources

No configuration in XML other than JNDI related bindings.

 My understanding was that:

 1. Tomcat does not remove the connection pool
 2. Once the shutdown process has started, no new requests will be
 handled by the currently-shutting-down context

 Could these two items give the result you are observing? It's easy
 enough to have your webapp close the DataSource (even though it's kinda
 stupid that Tomcat doesn't do it for you).

That depends on which shutdown it is. Understanding 2 is not correct
from my debugging. You can have a sequence of:
1. Connection pool closed
2. Request sent to servlet

This happens during tomcat shutdown and will trigger a new connection.
I suspect that similar sequence exists during redeploy. I cant recall
exactly what happened in this case, but I remember that it was in more
than one scenario. We decided to shut down tomcat every time and
forget about it, even though we do have a listener that closes pools,
along the same lines as the listener that you wrote I imagine.

If you want to add a listener that closes the pool, I would try adding
tomcat lifecycle listener to the context. You can handle event
Lifecycle.AFTER_STOP_EVENT. Try both listeners (web app and tomcat)
and see which one runs last, and put the code there. You have higher
probability of catching an open connection if you do it later. If the
listener is configured via tomcat and not the web app, you also get a
configuration that each party is responsible for cleaning up its own
bugs, as opposed to web app cleaning up tomcat bugs. Then the vision
of J2EE designers of separation of roles materializes :)

Elli

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



Re: DBCP woes (running out of cursors).

2009-10-26 Thread Elli Albek
Hi,
I did not follow this thread form the beginning, but I can provide a
few tips about using connection pools in tomcat.
1. DBCP has quite a few problems in the area of scalability. We have
our own modified version of the source that makes it more concurrent,
and I believe some of those changes were integrated into DBCP. Use the
latest stable version of DBCP form the commons project. It is a jar
file in tomcat that you can easily replace. The fixes do not require
using concurrent, that part of the code is not causing the problems.
2. If your JDBC driver supports caching of prepared statements and
metadata, do it in the driver and disable this in DBCP. IMO DBCP does
a poor job at best in caching. We use mysql and its JDBC driver is
doing an excellent job.
3. Your JDBC driver may already be caching metadata that DBCP is
caching. In this case you are caching the same data twice. Make sure
it dose not happen, it is a big memory overload on the JVM.
4. Tomcat has a problem doing a clean shutdown of DBCP, and other JNDI
resources. I traced in the debugger dangling connection pools that are
created during the shutdown process. If your pool is configure to ping
the connections once in a while, they can stay open for a long time,
possibly forever. Our solution is custom extension that cleans up
pools, which works in conjunction with our extended implementation of
DBCP.
5. The connection pool leak is caused mostly when war files are
replaced under load. If you are experiencing a problem of leaks in
those conditions, then some common options are:
A. Write custom extension to the pooling mechanism as we did. This is
not a 100% solution.
B. Avoid hot deployment of apps by shutting down tomcat before
updates. This is safer, but also not 100% clean.
C. Block Tomcat during the update. If you have a load balancer,
redirect traffic to other tomcat instances, and then do the update
while tomcat has no load. This reduces the problems significantly.

When you do a full tomcat shutdown, there will still be connections
that are not closed, but the process itself will finish, and the
database will clean up the connections after some time. This is of
course not as clean as closing all the connections on server shutdown,
but I don't know of any better option. I believe our custom cleanup
code does close most connections on shutdown, but I have no 100%
certainty or evidence that this is actually true. However it does do a
lot of closing that did not happen before.

I am not aware of any way to completely avoid dangling connection pool
after hot deployment under load. We tried to fix this but it got too
complicated, it is much easier to restart Tomcat and swallow the
bitter pill. You can still do hot deployment of war files that do not
access the database, though it is possible that the same leaks will
leave lots of hanging objects of other types (like email clients, JMS
clients, thread pools, HttpClient, etc).

E

On 10/26/09, Mark Thomas ma...@apache.org wrote:
 Bill Davidson wrote:
 Christopher Schultz wrote:
When you've played with it for a bit, tell us how things turned out.

 It's looking like optimal is caching about 40 PreparedStatement objects.
 However, I should qualify that noting that it's with our application and
 specifically with our little pummeling benchmark, which requests a
 specific
 subset of services, and probably isn't even a great test of real world
 traffic.
 It was mainly designed to see how the app handled being heavily stressed
 (like getting hit with 1000 requests at a time).

 The system is still about 3-4% slower with DBCP than with our old pooling
 library.  Our old pooling library did not wrap the Connection objects like
 DBCP does, though it did close old Connection objects so that they only
 got reused for up to two minutes at a time.  I'm actually a little
 surprised by
 this.  I would have expected that to make DBCP faster, since it keeps them
 open.

 The current DBCP (actually commons-pool) can struggle under very heavy
 load in multi-thread environments. There are plans afoot for a pool 2.0
 that will be based on java.util.concurrent that should enable much
 better multi-threaded performance.

 As always, it is best to check with a profiler to see what is actually
 slowing you down.

 Mark




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



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



Re: DBCP woes (running out of cursors).

2009-10-26 Thread Elli Albek
Hi,
More information about tomcat shutdown and object swapping probably belongs
in the development list. It is quite a bit of work to extend DBCP and write
extensions to tomcat, and at the end of the day most of those problems I
would consider as bugs. DBCP specifically cannot be easily extended, we had
to use the original source files with some modifications, my least favorite
option.

MySQL documentation covers their JDBC client configuration very well. The
number of options is little overwhelming, but after some time and a few
tests it is possible to find a configuration that is a match to the system
resources.
See:
http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-configuration-properties.html
The configuration is version specific, find your version before reading.

About the database clearing up dangling connections, you will have to read
the database documentation. I hate to say RTFM, but there is nothing else I
can say here :)

To disable caching in DBCP, use configuration option:
poolPreparedStatements=false

I don’t remember where exactly you specify it, since our extension just
passes a property file to DBCP. This is actually something that I would like
to see built into Tomcat/DBCP (property file configuration). Your system
admin will thank you.

To troubleshoot where caching is being done, your best bet is stepping
through the code with a debugger. Make sure the configuration of the test
system mirrors the production system.

It may not be possible to use the mysql caching algorithms, since they may
use features that are not publicly available through JDBC and are part of
their protocol. I don’t know the source well enough to comment on how it
works internally.

Specific example of leaks:
1.Close tomcat
2.Connection pool is removed.
3.Request comes in to the war file (the one that is in the closing
process)
4.Request gets processed.
5.Servlet needs a connection from DBCP.
6.Tomcat does not find the DBCP pool in JNDI, so it recreates it.
7.The newly created connection pool will not be used after this request,
and will not be closed. If the pool pings the connection, it will stay open.

A similar path I believe exists while hot deploying a war file, which also
exhibits the problem of handling requests in the middle of shutdown.

It has been a while since we worked on it, the details may vary from what is
listed above. However, one thing I do remember is that after some objects
were shut down Tomcat was still processing requests that required those
objects, and there was more than one way to reproduce it.

After all this work, we just shut down tomcat when we update war files.

It is possible to fix this. Two things that I would start with:
1.Standard server shutdown order. This is too much information for this
list.
2.Call shutdown callbacks of different APIs, give developer an option to
deal with it. For example JMX shutdown process does not happen correctly.

You may be able to fix this via listeners on various levels. We got to the
conclusion that shutting down objects in tomcat was little chaotic and no
one could say in confidence that using a certain listener API will work
better than another without spending a few days of tracing the code and
doing lots of tests. The problem is that in a simple invocation everything
seems to work fine, but if you throw in a few threads and methods that take
some time to respond then tracing becomes complicated and time intensive.
From my past experience multithreaded debugging can be time intensive,
especially when it involves so many components and possible paths as we have
in a full blown application container.

To make a long story short:
1.Disable caching in DBCP
2.Enable caching in your JDBC client
3.Shut down tomcat when you replace war files or when you change
configuration.

Elli

On Mon, Oct 26, 2009 at 6:54 PM, Martin Gainty mgai...@hotmail.com wrote:


 mggood work

  From: e...@sustainlane.com
  To: users@tomcat.apache.org
 
  Hi,
  I did not follow this thread form the beginning, but I can provide a
  few tips about using connection pools in tomcat.
  1. DBCP has quite a few problems in the area of scalability. We have
  our own modified version of the source that makes it more concurrent,
  and I believe some of those changes were integrated into DBCP. Use the
  latest stable version of DBCP form the commons project. It is a jar
  file in tomcat that you can easily replace. The fixes do not require
  using concurrent, that part of the code is not causing the problems.
  2. If your JDBC driver supports caching of prepared statements and
  metadata, do it in the driver and disable this in DBCP. IMO DBCP does
  a poor job at best in caching. We use mysql and its JDBC driver is
  doing an excellent job.
 mgis it possible to port the working (MySQL) Driver caching algorithms to
 DBCP?

  3. Your JDBC driver may already be caching metadata that DBCP is
  caching. In this case you are 

Re: How to know when tomcat is ready to serve request

2009-10-23 Thread Elli Albek
Notice that server life cycle listeners normally work in the server context, 
and not in a war file class loader. This may cause some problems for code in 
the war file accessing the objects that were created by the listener.

Something else that you should consider in tomcat 5.x versions is the shutdown, 
which may cause requests to be processed in the middle of shutdown, after some 
components were already stopped (meaning their shutdown callback method was 
called, and they released their resources). In JNDI it will cause released 
objects to re-instantiate themselves. So if you see your thread pool restarting 
after you issue a shutdown command under load, don't be surprised. The safest 
way I know around it is not have container based shutdown methods on the 
objects. Instead have a server lifecycle listener shut them down using 
proprietary methods that are not defined by the container interfaces (which you 
should implement as empty methods).

E

- Original Message -
From: Anup K Ram anupk...@gmail.com
To: Tomcat Users List users@tomcat.apache.org
Sent: Thu, 22 Oct 2009 20:58:37 -0700 (PDT)
Subject: Re: How to know when tomcat is ready to serve request

My problem here is I want to wake up the thread after the server is
completely started. I have not used Server LifeCycleListener before. I will
give it a try. Appreciate any help. Thanks.

On Thu, Oct 22, 2009 at 7:48 PM, Elli Albek e...@sustainlane.com wrote:

 If this is the case you can assume that the war file is deployed.

 I don't trust the code of the tomcat startup/shutdown. If you want to be
 100% safe use a server lifecytle listener. This is limited to a server that
 has the same apps, meaning you are not adding/removing/replacing
 applications on the fly. There is a higher probability that what you assume
 is running and not running based on event listeners is correct with
 lifecycle listener (higher, not 100%). This is for tomcat 5.x. in 6.x
 versions the event and lifecycle management may mirror more the actual
 lifecycle of objects.

 E


 - Original Message -
 From: Anup K Ram anupk...@gmail.com
 To: Tomcat Users List users@tomcat.apache.org
 Sent: Thursday, October 22, 2009 9:38:01 AM (GMT-0800) America/Los_Angeles
 Subject: Re: How to know when tomcat is ready to serve request

 The code is in a thread thats in turn spawned from the contextInitilized
 method of a ServletContextListener.(Inside the war)

 On Wed, Oct 21, 2009 at 11:53 PM, Elli Albek e...@sustainlane.com wrote:

  Where does the code that needs to know that reside? How is it
 initialized?
  Is it inside tomcat (war file, valve, JNDI resource) or outside the
 tomcat
  JVM?

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





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



Re: How can I prevent Quartz multiple execution after tomcat restart

2009-10-23 Thread Elli Albek
Where is your spring configuration file? Is it inside the war file?

When you have two hosts, do you have the war file in both? If this is he case 
you may deploy the entire war file twice. Generally a deployed war file can run 
only in one host. If you run it in two hosts, you are deploying the entire war 
file twice. This will create two instances of your quartz object.

If all you need is multiple domains mapped to the same application, try 
replacing 

Host name=localhost ../Host
Host name=XXX.com../Host

With:
Host name=localhost ...
AliasXXX.com/Alias
.../Host

E

- Original Message -
From: zlzc2000 zlzc2...@hotmail.com
To: users@tomcat.apache.org
Sent: Fri, 23 Oct 2009 00:28:16 -0700 (PDT)
Subject: How can I prevent Quartz multiple execution after tomcat restart


hallo,

we have problem with Quartz and Tomcat.
Im using tomcat 5.5
i using 'localhost' to deploy a Spring project on server.
after deploy run Quartz the job once time. this is right.
but after restart tomcat, execute the same jobs twice at the same time.
(project new deploy then no problem, only after tomcat stop-start or
restart, then comming problem)
(2 quartz instanz created and started)

in server.xml i use two Host tags 1: Host name=localhost ... 2:Host
name=XXX.com... if i use only one host, for example only Host
name=XXX.com..., then no problem., but by which i can not use interface
of tomcat.

a strange thing: in tomcat management interface i have stoped project, but
even though, in catalina.out can ich see, there is still one quartz job run.
I CANT UNDERSTAND!

how can i prevent it?
follow code are our server.xml code


Host name=localhost appBase=webapps
unpackWARs=true autoDeploy=false
xmlValidation=false xmlNamespaceAware=false
/Host

Host name=XXX.com
unpackWARs=true autoDeploy=false deployOnStartup=false
xmlValidation=false xmlNamespaceAware=false
Aliaswww.XXX.com/Alias
Context path=
docBase=/var/lib/tomcat55/webapps/xxx
reloadable=true
Realm className=org.apache.catalina.realm.JDBCRealm
driverName=org.postgresql.Driver
connectionURL=jdbcostgresql://localhost:5432/xxx
connectionName=postgres connectionPassword= userTable=users_password
userNameCol=userid userCredCol=password
userRoleTable=user_role roleNameCol=rolename
digest=MD5/
/Context
/Host
... 

follow code are configuration of Quartz in applicationContex.xml

bean id=robotSearchSwapper
class=org.springframework.scheduling.quartz.Metho
dInvokingJobDetailFactoryBean
property name=targetObject
ref bean=swapperService /
/property
property name=targetMethod
valuerobotSearch/value
/property
property name=concurrent value=false /
/bean

bean id=robotSearchTrigger
class=org.springframework.scheduling.quartz.Simpl eTriggerBean
property name=jobDetail ref=robotSearchSwapper/

property name=startDelay
value18/value
/property
property name=repeatInterval
value30/value
/property
/bean
bean id=scheduler class=org.springframework.scheduling.quartz.Sched
ulerFactoryBean
property name=quartzProperties
props
prop key=org.quartz.threadPool.classorg.quartz.simpl
.SimpleThreadPool/prop
prop key=org.quartz.threadPool.threadCount1/prop
prop key=org.quartz.threadPool.threadPriority1/prop
prop key=org.quartz.threadPool.threadsInheritContextCl
assLoaderOfInitializingThreadtrue/prop
/props
/property

property name=triggers
list
ref local=robotSearchTrigger/
/list
/property
/bean

-- 
View this message in context: 
http://www.nabble.com/How-can-I-prevent-Quartz-multiple-execution-after-tomcat-restart-tp26021949p26021949.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


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




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



Re: Does Tomcat http support subdomains?

2009-10-22 Thread Elli Albek
 My initial response to that article is that it's vague drivel.

 If you are an incredibly savvy and experienced web developer, no doubt 
 you already have a DreamHost account - should be all you need to read 
 to make a reasonable critical assessment of the quality of this article.

:)

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



Re: Cannot set remote address in valve (Tomcat 5.5)

2009-10-22 Thread Elli Albek
Makes sense. I did not dig through the code of the full version RemoteIpValve 
so much, just enough to get the general idea (or maybe just enough to get into 
trouble).

I have to look at the docs of our load balancer or maybe just add the proto 
header to the log files to see what values it gets. I know that with squid we 
are fine, and the server is generally accessible only through the load balancer 
or reverse proxy.

If I can make a suggestion for the docs on google code, be specific that this 
valve should be in the engine and precede all other elements of the engine. 
This makes everything work smoothly. It may also be possible to put it outside 
the engine, not sure if that is a general safe case.

I think the only real solution here is as you implemented, a valve that 
precedes log valves and other valves (many of which use the IP). Keeps the rest 
of the code clean and simple, the configuration is in one place instead of all 
over the place.

By the way is it proxied or proxyfied request? :)

E

- Original Message -
From: Cyrille Le Clerc clecl...@xebia.fr
To: Tomcat Users List users@tomcat.apache.org
Sent: Wed, 21 Oct 2009 06:31:57 -0700 (PDT)
Subject: Re: Cannot set remote address in valve (Tomcat 5.5)

   Hello Elli,

   From what I understand of your architecture, I would configure
RemoteIpValve with :

Valve
className   = org.apache.catalina.connector.RemoteIpValve
internalProxies = @load-balancer-ip
trustedProxies  = @the-trusted-proxy-that-is-not-the-load-balancer
protocolHeader = x-forwarded-proto /

Note :
- do not forget to regexp escape' the ip adresses in internalProxies
and trustedProxies attributes.
- do not declare protocolHeader=x-forwarded-proto if your load
balancer do not manage it
- more docs at http://code.google.com/p/xebia-france/wiki/RemoteIpValve

Thanks to this,
- the 99% direct requests will reach Tomcat with x-forwarded-for=@clientIp
- 1% proxyfied requests will reach Tomcat with
x-forwarded-for=@clientIp,
@the-trusted-proxy-that-is-not-the-load-balancer

Does it make sense ?

Cyrille

--
Cyrille Le Clerc
clecl...@xebia.fr cyri...@cyrilleleclerc.com
http://blog.xebia.fr

On Wed, Oct 21, 2009 at 6:57 AM, Elli Albek e...@sustainlane.com wrote:

 A question: How do you know that a proxy is trusted? Is it by providing a 
 list of trusted IPs in the configuration of the filter?

 Our load balancer is always adding the client IP as the first in the list, 
 and it does not add its own IP to the list. The header
 has one IP +99% of the times, the other times there is an additional IP of a 
 proxy that is not our load balancer (reverse proxy).

 So in that case, we can check that the request comes from a trusted IP list 
 (known load balancers), and only then try to change the
 IP. If the client IP does not come from the load balancer, it is basically a 
 pass through.

 For our system the first IP is what the load balancer sees, and the only way 
 to spoof it is to access the server not through the
 load balancer. If you send a request with a spoofed header to the laod 
 balancer, it will still add the IP of the spoofer in the
 beginning of the list.

 This may not be the general case for proxies, it is only for this case.

 E

 -Original Message-
 From: Cyrille Le Clerc [mailto:clecl...@xebia.fr]
 Sent: Thursday, October 08, 2009 1:04 AM
 To: Tomcat Users List
 Subject: Re: Cannot set remote address in valve (Tomcat 5.5)

   Hello Elli,

   I am afraid there may be a flaw in the algorythm looking for the
 first IP  of the coma delimited x-forwarded-for header without
 ensuring that this first IP has been set by a trusted proxy and not by
 the requester ( getFirstIP(xforwardedForHeaderValue) ). Such spoofing
 can easily be achieved with tools like Firefox add-ons Modify Headers
 (1) and X-Forwarded-For Spoofer (2) .

   The forthcoming version of Apache Httpd will offer a secure
 mechanism to handle X-Forwarded-For with a module called mod_remoteip
 (3). It relies on the concept of trusted proxies which IP address can
 be 'swallowed'. The first IP of the list that is not a trusted proxy
 is seen as the real remote ip. mod_remoteip would not have been
 tricked by such x-forwarded-for header spoofing.

   Here are two java ports of mod_remoteip to handle X-Forwarded-For
 at the Tomcat level with a valve and at the WAR level with a servlet
 filter : RemoteIpValve (4) and XForwardedFilter (5). In addition to
 handle X-Forwarded-For, they also integrate X-Forwarded-Proto (ssl).
 These java ports integrate the same trusted proxies concept to prevent
 spoofing.

   Cyrille
 --
 Cyrille Le Clerc
 clecl...@xebia.fr cyri...@cyrilleleclerc.com
 http://blog.xebia.fr


 (1) https://addons.mozilla.org/en-US/firefox/addon/967
 (2) https://addons.mozilla.org/en-US/firefox/addon/5948
 (3) http://httpd.apache.org/docs/trunk/mod/mod_remoteip.html
 (4) http://code.google.com/p/xebia-france/wiki/RemoteIpValve
 (5) http://code.google.com/p/xebia-france/wiki

Re: How to know when tomcat is ready to serve request

2009-10-22 Thread Elli Albek
Where does the code that needs to know that reside? How is it initialized? Is 
it inside tomcat (war file, valve, JNDI resource) or outside the tomcat JVM?

E

- Original Message -
From: Anup K Ram anupk...@gmail.com
To: users@tomcat.apache.org
Sent: Wed, 21 Oct 2009 16:56:50 -0700 (PDT)
Subject: How to know when tomcat is ready to serve request

Hi,
Is there a way to know whether tomcat is started successfully and ready to
serve requests? I need to know this programmatically.

Thanks In Advance.



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



Re: Valves being converted to Filters?

2009-10-22 Thread Elli Albek
This is my concern as well. Our custom login valve is using values from the 
form authentication valve that are not accessible in the war file. For example 
they allow reconstruction of a post request and replacing roles and principals, 
which I doubt can be done with a filter in a simple way without repeating a lot 
of code. Even though there is a lot in common, I would like to have access to 
the tomcat internal data and not be limited to the application level API. Valve 
cam use HttpServletRequest and response, if you know that you can cast them to 
an internal class with the full API. In that case it may be safer to just use 
that class in the method signatures.

E

- Original Message -
From: Christopher Schultz ch...@christopherschultz.net
To: Tomcat Users List users@tomcat.apache.org
Sent: Wed, 21 Oct 2009 08:11:17 -0700 (PDT)
Subject: Re: Valves being converted to Filters?

Will there be a way to grab information from the raw request as seen
by a Valve today? It's nice to be able to get and set values above (or
below, depending on your POV) the servlet API.

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



Re: How to know when tomcat is ready to serve request

2009-10-22 Thread Elli Albek
If this is the case you can assume that the war file is deployed.

I don't trust the code of the tomcat startup/shutdown. If you want to be 100% 
safe use a server lifecytle listener. This is limited to a server that has the 
same apps, meaning you are not adding/removing/replacing applications on the 
fly. There is a higher probability that what you assume is running and not 
running based on event listeners is correct with lifecycle listener (higher, 
not 100%). This is for tomcat 5.x. in 6.x versions the event and lifecycle 
management may mirror more the actual lifecycle of objects.

E


- Original Message -
From: Anup K Ram anupk...@gmail.com
To: Tomcat Users List users@tomcat.apache.org
Sent: Thursday, October 22, 2009 9:38:01 AM (GMT-0800) America/Los_Angeles
Subject: Re: How to know when tomcat is ready to serve request

The code is in a thread thats in turn spawned from the contextInitilized
method of a ServletContextListener.(Inside the war)

On Wed, Oct 21, 2009 at 11:53 PM, Elli Albek e...@sustainlane.com wrote:

 Where does the code that needs to know that reside? How is it initialized?
 Is it inside tomcat (war file, valve, JNDI resource) or outside the tomcat
 JVM?

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



Re: Starting web app with properties set

2009-10-22 Thread Elli Albek
Load the properties using java.util.Properties, and store them in a place that 
is accessible in the war (like a static variable or context attribute).

If you are thinking about properties such as database/mail server connections, 
then keep the OUTSIDE of the war file, not in XML or other things that will 
require your sys admin to open war files and change them, or mix tomcat 
configuration with application database connection properties, etc.

A good place for you property files is [tomcat]/shared/classes. Property files 
in this folder are accessible to the war files via the standard class loader. 
The down side is that the same file is accessible to all, so if you need a 
separate configuration for each war you will have to use different file names.

E

- Original Message -
From: Ken T. ktectr...@gmail.com
To: users@tomcat.apache.org
Sent: Thursday, October 22, 2009 9:58:33 AM (GMT-0800) America/Los_Angeles
Subject: Starting web app with properties set

I looked around online but couldn't find anything.  Is there a way to 
start a web application under Tomcat with specific properties mappings.  
Say I wanted to start my app with the property setting:

user.database=ProdDB

How would I go about doing so?

Thank you,


-- 
Ken T. ktectr...@gmail.com


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



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



RE: Valves being converted to Filters?

2009-10-20 Thread Elli Albek
So is there still going to be an API to plug into the tomcat internals and do 
things that the servlet API does not support?

E

-Original Message-
From: Cyrille Le Clerc [mailto:clecl...@xebia.fr] 
Sent: Tuesday, October 20, 2009 4:06 PM
To: Tomcat Users List
Subject: Re: Valves being converted to Filters?

   Hello Henri,

   I was referring to public information such as :
- Google Summer Of Code 2009, project Convert current Tomcat valves
to Servlet Filters : http://wiki.apache.org/tomcat/SummerOfCode2009
and the various associated emails on Tomcat dev mailing list.
- Mark Thomas post on Tomcat users mailing list : ...47330 is on the
todo list but my current plan is to implement it as a Filter rather
than a valve.  (1)

   However, my understanding is not that pluggable 'interceptors' will
be removed from the container, just that the Valve API will be
replaced with a Filter API. I feel interfaces (HttpServletRequest 
HttpServletResponse) will be much more easy to manipulate than the
current implementations (Request, Response).

   Hopr this clarifies my message,

   Cyrille


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



RE: Cannot set remote address in valve (Tomcat 5.5)

2009-10-20 Thread Elli Albek
A question: How do you know that a proxy is trusted? Is it by providing a list 
of trusted IPs in the configuration of the filter?

Our load balancer is always adding the client IP as the first in the list, and 
it does not add its own IP to the list. The header
has one IP +99% of the times, the other times there is an additional IP of a 
proxy that is not our load balancer (reverse proxy).

So in that case, we can check that the request comes from a trusted IP list 
(known load balancers), and only then try to change the
IP. If the client IP does not come from the load balancer, it is basically a 
pass through.

For our system the first IP is what the load balancer sees, and the only way to 
spoof it is to access the server not through the
load balancer. If you send a request with a spoofed header to the laod 
balancer, it will still add the IP of the spoofer in the
beginning of the list.

This may not be the general case for proxies, it is only for this case.

E

-Original Message-
From: Cyrille Le Clerc [mailto:clecl...@xebia.fr] 
Sent: Thursday, October 08, 2009 1:04 AM
To: Tomcat Users List
Subject: Re: Cannot set remote address in valve (Tomcat 5.5)

   Hello Elli,

   I am afraid there may be a flaw in the algorythm looking for the
first IP  of the coma delimited x-forwarded-for header without
ensuring that this first IP has been set by a trusted proxy and not by
the requester ( getFirstIP(xforwardedForHeaderValue) ). Such spoofing
can easily be achieved with tools like Firefox add-ons Modify Headers
(1) and X-Forwarded-For Spoofer (2) .

   The forthcoming version of Apache Httpd will offer a secure
mechanism to handle X-Forwarded-For with a module called mod_remoteip
(3). It relies on the concept of trusted proxies which IP address can
be 'swallowed'. The first IP of the list that is not a trusted proxy
is seen as the real remote ip. mod_remoteip would not have been
tricked by such x-forwarded-for header spoofing.

   Here are two java ports of mod_remoteip to handle X-Forwarded-For
at the Tomcat level with a valve and at the WAR level with a servlet
filter : RemoteIpValve (4) and XForwardedFilter (5). In addition to
handle X-Forwarded-For, they also integrate X-Forwarded-Proto (ssl).
These java ports integrate the same trusted proxies concept to prevent
spoofing.

   Cyrille
--
Cyrille Le Clerc
clecl...@xebia.fr cyri...@cyrilleleclerc.com
http://blog.xebia.fr


(1) https://addons.mozilla.org/en-US/firefox/addon/967
(2) https://addons.mozilla.org/en-US/firefox/addon/5948
(3) http://httpd.apache.org/docs/trunk/mod/mod_remoteip.html
(4) http://code.google.com/p/xebia-france/wiki/RemoteIpValve
(5) http://code.google.com/p/xebia-france/wiki/XForwardedFilter


On Mon, Oct 5, 2009 at 11:19 PM, Elli Albek e...@sustainlane.com wrote:

 Hi,

 We can add the header to the custom valves, but then in addition we have to
 change a few log file configurations, create a servlet filter and maybe
 something else I cant think of now. Basically doing the same thing a few
 times and keeping track of all the places that depend on the header. Ideally
 this would all be corrected once in the beginning of the request processing
 pipeline, so log file configuration, other valves and the war files will
 remain unchanged.



 Attached a Valve that does that. This is the minimum code necessary, so it
 should not have any significant performance impact.

 Feel free to use as is, not guaranteed to work, no expressed on implied
 warranties, not FDIC insured and may loose value.



 To configure Tomcat add to server.xml:



 Service name=Catalina

      Connector port=8080 .../

      Engine defaultHost=localhost name=Catalina

            !-- This should precede all other configuration in the engine
 --

            Valve className=org.apache.catalina.connector.RemoteIPValve/



 Java class/jar should be placed in /server/lib or /server/classes



 E







 package org.apache.catalina.connector;



 import java.io.IOException;

 import java.util.regex.Matcher;

 import java.util.regex.Pattern;



 import javax.servlet.ServletException;



 import org.apache.catalina.connector.Request;

 import org.apache.catalina.connector.Response;

 import org.apache.catalina.valves.ValveBase;



 /**

  * A valve that extracts the remote IP of the client from an HTTP header
 field

  * passed by the proxy, and set it in the request as the original client IP.

  * This valve should be the first valve in the engine, so log valves (and

  * others) will see the real client IP without requiring the same code
 again.

  *

  * @author Elli Albek, www.sustainlane.com

  */

 public class RemoteIPValve extends ValveBase {



      private static final Pattern ipExpr =
 Pattern.compile(^[\\da-fA-F]+(\\.[\\da-fA-F]+)+);



      private String forwardedForHeader = X-Forwarded-For;



      public void invoke(Request request, Response response) throws
 IOException, ServletException {



            String header = request.getHeader

Re: Cannot set remote address in valve (Tomcat 5.5)

2009-10-05 Thread Elli Albek

- Original Message -
From: Christopher Schultz ch...@christopherschultz.net
To: Tomcat Users List users@tomcat.apache.org
Sent: Fri, 2 Oct 2009 07:32:06 -0700 (PDT)
Subject: Re: Cannot set remote address in valve (Tomcat 5.5)


 2. There are other valves like request filters that cannot work without the
 correct IP, as well as custom login valve.

 Filters should be OK providing they are defined in the right order.

 Aren't all Valves always called before Filters?

To be more specific, i was referring to a request filter that is implemented 
as a valve, not as a servlet filter. One is shipped with tomcat already for 
filtering IPs. That valve does not work behind a load balancer or a reverse 
proxy.

E

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



Re: Cannot set remote address in valve (Tomcat 5.5)

2009-10-05 Thread Elli Albek
To make it clear, valves are executed around the web apps, so they are executed 
before the request gets to any servlet filter. Servlet filter behavior is 
defined by the Servlet specification. Valves are tomcat specific classes that 
contain some core server functionality that is not defined by the spec as an 
interface.

E

- Original Message -
From: Tim Funk funk...@apache.org
To: Tomcat Users List users@tomcat.apache.org
Sent: Fri, 2 Oct 2009 07:46:14 -0700 (PDT)
Subject: Re: Cannot set remote address in valve (Tomcat 5.5)

Context filters are executed before webapp filters. I believe (but not 
confirmed) that valves execute before the filters.

-Tim

Christopher Schultz wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 Mark,
 
 On 10/2/2009 5:55 AM, Mark Thomas wrote:
 Elli Albek wrote:
 A few reasons why not to do this as a servlet filter:

 1. There are many web apps on the server and I don't want to include the
 filter in each.
 You don't have to. Configure it in the global web.xml.
 
 Are the filters configured in conf/web.xml considered before those in
 WEB-INF/web.xml... that is, will they be called before the
 webapp-defined ones?
 
 2. There are other valves like request filters that cannot work without the
 correct IP, as well as custom login valve.
 Filters should be OK providing they are defined in the right order.
 
 Aren't all Valves always called before Filters?
 


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




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



RE: Cannot set remote address in valve (Tomcat 5.5)

2009-10-05 Thread Elli Albek
Hi,

We can add the header to the custom valves, but then in addition we have to
change a few log file configurations, create a servlet filter and maybe
something else I cant think of now. Basically doing the same thing a few
times and keeping track of all the places that depend on the header. Ideally
this would all be corrected once in the beginning of the request processing
pipeline, so log file configuration, other valves and the war files will
remain unchanged.

 

Attached a Valve that does that. This is the minimum code necessary, so it
should not have any significant performance impact. 

Feel free to use as is, not guaranteed to work, no expressed on implied
warranties, not FDIC insured and may loose value.

 

To configure Tomcat add to server.xml:

 

Service name=Catalina

  Connector port=8080 .../ 

  Engine defaultHost=localhost name=Catalina

!-- This should precede all other configuration in the engine
--

Valve className=org.apache.catalina.connector.RemoteIPValve/

 

Java class/jar should be placed in /server/lib or /server/classes

 

E

 

 

 

package org.apache.catalina.connector;

 

import java.io.IOException;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

import javax.servlet.ServletException;

 

import org.apache.catalina.connector.Request;

import org.apache.catalina.connector.Response;

import org.apache.catalina.valves.ValveBase;

 

/**

 * A valve that extracts the remote IP of the client from an HTTP header
field

 * passed by the proxy, and set it in the request as the original client IP.

 * This valve should be the first valve in the engine, so log valves (and

 * others) will see the real client IP without requiring the same code
again.

 * 

 * @author Elli Albek, www.sustainlane.com

 */

public class RemoteIPValve extends ValveBase {

 

  private static final Pattern ipExpr =
Pattern.compile(^[\\da-fA-F]+(\\.[\\da-fA-F]+)+);

 

  private String forwardedForHeader = X-Forwarded-For;

 

  public void invoke(Request request, Response response) throws
IOException, ServletException {

 

String header = request.getHeader(forwardedForHeader);

String forwardedIP = getFirstIP(header);

if (forwardedIP != null)

  request.remoteAddr = forwardedIP;

 

next.invoke(request, response);

  }

 

  /**

   * Return the first IP address in a string that may contain an IP list

   */

  static final String getFirstIP(String header) {

if (header == null)

  return null;

Matcher m = ipExpr.matcher(header);

if (m.find()) {

  return m.group();

}

return null;

  }

 

  public void setForwardedForHeader(String forwardedForHeader) {

this.forwardedForHeader = forwardedForHeader;

  }

 

  public String getInfo() {

return RemoteIPValve;

  }

}



RE: Cannot set remote address in valve (Tomcat 5.5)

2009-10-02 Thread Elli Albek
Yes, the remoteAddress member is protected. So you can only access it if you
put your class in the same package.

I thought of doing it like a filter (wrapping) but it does not look like a
workable solution in this case.

1. The request class is final (which basically ends the discussion :)
2. This class is not a simple placeholder for values or a wrapper. It is a
heavy object that is recycled at the end of the request processing and
contains a lot of code. I don't have any intention to get into Tomcat
internal resource management and object recycling code. It seems pretty
complicated. I don't think you can just replace a server object as you can
do with a servlet request wrapper that is basically a proxy.

E

-Original Message-
From: Christopher Schultz [mailto:ch...@christopherschultz.net] 
Sent: Thursday, October 01, 2009 8:43 AM
To: Tomcat Users List
Subject: Re: Cannot set remote address in valve (Tomcat 5.5)

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Elli,

On 9/27/2009 12:19 AM, Elli Albek wrote:
 public void setRemoteAddr(String remoteAddr) {
 // Not used
 }
 
 The variable is protected so I cannot access it directly from my code.

What variable? The remoteAddress member?

 Is there any way to implement this Valve?

Wrap the request object in a subclass that you write. This will allow
you to either

a) Override the setRemoteAddress method to return whatever you want
b) Explicitly set the remoteAddress member to whatever you want

- -chris
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrEzh0ACgkQ9CaO5/Lv0PAmqwCeJpvyj0k9Ze+QKLkyRNqfpvzp
nccAniLAI/gdF65qw9EF6HLsXqcSgacP
=S2JM
-END PGP SIGNATURE-

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



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



RE: Cannot set remote address in valve (Tomcat 5.5)

2009-10-02 Thread Elli Albek
A few reasons why not to do this as a servlet filter:

1. There are many web apps on the server and I don't want to include the
filter in each.
2. There are other valves like request filters that cannot work without the
correct IP, as well as custom login valve.
3. We have a few environments and I don't want to have different war
configurations for each. We had servers with and without load balancers and
I can see that change again in the near future. This should not affect the
application configuration.
4. It is logically part of the server environment and not part of the web
application. The web application should not change based on the network
architecture. If the system admin adds/removes the load balancer then he
should know about one thing he needs to change in tomcat, and not rebuild
all the wars without a filter. Network configuration should not require code
rebuild with/without filters (we have to do a build to create war, like most
people).

E

--
What about just implementing this as a filter and then construct a
request wrapper in the filter to read that header and override the
getRemoteAddr() method.

--David

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



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



Re: Cannot set remote address in valve (Tomcat 5.5)

2009-09-27 Thread Elli Albek
Thanks for the response. Is there any problem in fixing this method to actually 
set the variable (which is already in the class)?

I think the set methods should actually set the values, so others can write 
such extensions without putting their code in the apache packages.

Right now I guess the only thing I can do is to either use the valve class 
referenced in this bug report or put my class in an apache package, which I 
don't think it belongs to.

I see that the class you pointed to is also in an apache package just for that 
reason.

E

- Original Message -
From: Mark Thomas ma...@apache.org
To: Tomcat Users List users@tomcat.apache.org
Sent: Sun, 27 Sep 2009 02:13:49 -0700 (PDT)
Subject: Re: Cannot set remote address in valve (Tomcat 5.5)

https://issues.apache.org/bugzilla/show_bug.cgi?id=47330 is on the todo
list but my current plan is to implement it as a Filter rather than a valve.

What is the issue with using a Filter?

If you really want to write a filter than that bug report should be all
you need.

Mark




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




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



Cannot set remote address in valve (Tomcat 5.5)

2009-09-26 Thread Elli Albek
Hi,
We have Tomcat behind a load balancer. The servlet API and tomcat libraries
see the load balancer IP as the client IP.

I tried to write a simple valve which will extract the IP from HTTP header 
X-Forwarded-For
and continue the valve chain using this IP as the client IP. This will be
the first valve in the chain, so everything will work as normal afterwards
including log files, IP filter valve, etc.

The problem I am facing, is when I try to set the remote IP on the request
from my valve, the code does nothing. This is the set method in the class
org.apache.catalina.connector.Request:

public void setRemoteAddr(String remoteAddr) {
// Not used
}

The variable is protected so I cannot access it directly from my code.

Is there any way to implement this Valve?

Is there anything already shipped in tomcat to extract the client IP from
the header?

I DO NOT want to write a servlet filter for various reasons, so I hope there
is a way to do it with a valve.

Any help appreciated.


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