Re: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-30 Thread Mark Thomas

On 29/05/2024 17:03, Eric Robinson wrote:




One of the webapps is related to voice reminder messages that go out to people. 
The reminders go out sometime after 9 am, which tracks with the slowdowns.


Ack.

Something to try while I work on a patch is setting 
archiveIndexStrategy="bloom" on the resources.


You'd configure that in META-INF/context.xml something like this:


  


Mark

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



Re: PersistentManager and ClassNotFoundException

2024-05-30 Thread Jakub Królikowski
Hello Chris,

On Tue, May 28, 2024 at 6:38 PM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> Jakub,
>
> On 5/24/24 09:31, Jakub Królikowski wrote:
> > On Fri, May 24, 2024 at 11:23 AM Mark Thomas  wrote:
> >
> >> Can you provide the simplest web application (with source) that
> >> replications the problem?
> >>
> >> Mark
> >>
> >>
> >> On 23/05/2024 23:45, Jakub Królikowski wrote:
> >>> Hi,
> >>>
> >>> I'm working with Tomcat 10.1.
> >>>
> >>> When a user starts using the store in my web application, I save the
> >>> ShopCart object on the "cart" session attribute.
> >>> I want the "cart" attributes to return to the session after restarting
> >> the
> >>> app.
> >>>
> >>>
> >>> To enable session persistence I added
> >>>
> >>> 
> >>>
> >>> to the Context. It loads the StandardManager.
> >>>
> >>> And this works fine - after reload / restart the object "ShopCart" is
> >> back
> >>> in the session.
> >>>
> >>>
> >>>
> >>> I want to experiment with PersistentManager. Tomcat docs says: "
> >>> The persistence across restarts provided by the *StandardManager* is a
> >>> simpler implementation than that provided by the *PersistentManager*.
> If
> >>> robust, production quality persistence across restarts is required then
> >> the
> >>> *PersistentManager* should be used with an appropriate configuration.
> >>>
> >>> "
> >>>
> >>> I hope for a Listener of deserialization of the session attributes.
> >>>
> >>> The new Manager configuration looks like this:
> >>>
> >>>  >>> maxActiveSessions="2" saveOnRestart="true">
> >>>
> >>>  >>> "c:\tomcat10\sessionperm"/>
> >>>
> >>> 
> >>>
> >>> But it doesn't work. After restart I get this exception:
> >>>
> >>>
> >>> java.lang.ClassNotFoundException: ShopCart
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1332)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1144)
> >>>
> >>> at java.base/java.lang.Class.forName0(Native Method)
> >>>
> >>> at java.base/java.lang.Class.forName(Class.java:534)
> >>>
> >>> at java.base/java.lang.Class.forName(Class.java:513)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.util.CustomObjectInputStream.resolveClass(CustomObjectInputStream.java:158)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2061)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readClassDesc(ObjectInputStream.java:1927)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2252)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readObject0(ObjectInputStream.java:1762)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readObject(ObjectInputStream.java:540)
> >>>
> >>> at
> >>> java.base/java.io
> >> .ObjectInputStream.readObject(ObjectInputStream.java:498)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1198)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:831)
> >>>
> >>> at org.apache.catalina.session.FileStore.load(FileStore.java:203)
> >>>
> >>> at
> >> org.apache.catalina.session.StoreBase.processExpires(StoreBase.java:138)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.session.PersistentManagerBase.processExpires(PersistentManagerBase.java:409)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:587)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:4787)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1172)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1176)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1176)
> >>>
> >>> at
> >>>
> >>
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1154)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
> >>
> >
> >
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
> >>>
> >>> at
> >>>
> >>
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
> >>>
> >>> at
> >>>
> >>
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
> >>>
> >>> at java.base/java.lang.Thread.run(Thread.java:1583)

Write listener question

2024-05-30 Thread joan.balaguero
Hello,

I have a NIO connector with an asynchronous servlet with its write listener.

@Override
 public void onWritePossible() throws IOException {

  if (this.isFirst) {
this.os = this.asyncContext.getResponse().getOutputStream();
this.startIdx = 0;
this.endIdx = WRITE_BUFFER_SIZE;
  }
 
 while (this.startIdx < this.endIdx && this.os.isReady()) {
 this.os.write(this.response, this.startIdx, this.endIdx - this.startIdx);

 this.startIdx = this.endIdx;
 this.endIdx += WRITE_BUFFER_SIZE;
 if (this.endIdx > this.response.length) this.endIdx = this.response.length;
  }

  if (this.startIdx == this.endIdx) {
this.ac.complete();
  }
}

Only when the response to return is bigger than 32K then:
1. Writing the response in chunks of WRITE_BUFFER_SIZE  = 32K, sometimes our 
client receives the response in wrong order (complete, all bytes written, but 
in different order).
2. Setting a WRITE_BUFFER_SIZE  = 8K seems to fix this issue.

But it's weird, this is only happening in this client, we have other 
installations returning responses of megabytes with no issues.

So just a couple of questions:

1. Do you think the implementation of the onWritePossible method above is 
correct?
2. Is it worth to provide a buffered implementation of the ServletOuputStream 
to write the response?


Thanks,

Joan.


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



RE: Write listener question

2024-05-30 Thread joan.balaguero
Sorry, this issue happens with both Tomcat 8.5.x and 10.1.x.

-Original Message-
From: joan.balagu...@ventusproxy.com  
Sent: Thursday, May 30, 2024 11:57 AM
To: 'Tomcat Users List' 
Subject: Write listener question

Hello,

I have a NIO connector with an asynchronous servlet with its write listener.

@Override
 public void onWritePossible() throws IOException {

  if (this.isFirst) {
this.os = this.asyncContext.getResponse().getOutputStream();
this.startIdx = 0;
this.endIdx = WRITE_BUFFER_SIZE;
  }
 
 while (this.startIdx < this.endIdx && this.os.isReady()) {
 this.os.write(this.response, this.startIdx, this.endIdx - this.startIdx);

 this.startIdx = this.endIdx;
 this.endIdx += WRITE_BUFFER_SIZE;
 if (this.endIdx > this.response.length) this.endIdx = this.response.length;
  }

  if (this.startIdx == this.endIdx) {
this.ac.complete();
  }
}

Only when the response to return is bigger than 32K then:
1. Writing the response in chunks of WRITE_BUFFER_SIZE  = 32K, sometimes our 
client receives the response in wrong order (complete, all bytes written, but 
in different order).
2. Setting a WRITE_BUFFER_SIZE  = 8K seems to fix this issue.

But it's weird, this is only happening in this client, we have other 
installations returning responses of megabytes with no issues.

So just a couple of questions:

1. Do you think the implementation of the onWritePossible method above is 
correct?
2. Is it worth to provide a buffered implementation of the ServletOuputStream 
to write the response?


Thanks,

Joan.


-
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: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-30 Thread Christopher Schultz

Eric,

On 5/29/24 12:10, Eric Robinson wrote:



-Original Message-
From: Mark Thomas 
Sent: Wednesday, May 29, 2024 10:19 AM
To: users@tomcat.apache.org
Subject: Re: Database Connection Requests Initiated but Not Sent on the Wire
(Some, Not All)

On 29/05/2024 16:08, Eric Robinson wrote:


I believe your assessment is correct. How hard is it to enable pooling? Can it

be bolted on, so to speak, through changes to the app context, such that the
webapp itself does not necessarily need to implement special code?

It looks like - from the database configuration you provided earlier - there is 
an
option to configure the database via JNDI. If you do that with Tomcat you will
automatically get pooling. That might be something to follow up with the
vendor. If you go that route, I'd recommend configuring the pool to remove
abandoned connections to avoid any issues with connection leaks.



In reviewing live threads with Visual VM, I note that there are apparently 
threads related to cleaning up abandoned connections, and maybe even pooling?

The threads are:

mysql-cj-abandoned-connection-cleanup (2 of those)


This thread is started by the MySQL driver to clean-up certain resources 
and isn't related to connection pooling. I've had issues with these 
things not shutting down on application-stop in certain versions of 
MySQL's driver. :/



OkHttp Connection Pool (2 of those)
OkHttp https://ps.pndsn.com (not sure what that is)


OkHttp is a network connection pool for HTTP connections. It's not 
related to dB connection pooling.


Most pools do not have any extra threads required, so you wouldn't find 
any evidence of such things running in your system.


-chris

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



Re: PersistentManager and ClassNotFoundException

2024-05-30 Thread Christopher Schultz

Jakub,

On 5/30/24 05:25, Jakub Królikowski wrote:

Where is your  configuration located? It *should* be inside
your  located in META-INF/context.xml in your web application.
If it's in there, then everything it does should be in the context (and
ClassLoader) of your web application -- where your classes should be
locatable.

If you have it anywhere else, it probably won't work the way you expect
it to work.


Yes, you are right! Thank you for this hint!
I have configured  in /conf/server.xml.
And indeed - interestingly, StandardManager, works correctly even there!
PersistentManager, however, does not.
After moving the configuration to /META-INF/context.xml, both
managers work fine.
It may be worth mentioning this in the documentation:
https://tomcat.apache.org/tomcat-10.1-doc/config/manager.html#Persistence_Across_Restarts


Would you like to provide a documentation patch/PR that works for you?

-chris

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



Re: Write listener question

2024-05-30 Thread Christopher Schultz

Joan,

Please don't hijack threads. Start a new message to the list without 
replying to an existing one.


-chris

On 5/30/24 06:03, joan.balagu...@ventusproxy.com wrote:

Sorry, this issue happens with both Tomcat 8.5.x and 10.1.x.

-Original Message-
From: joan.balagu...@ventusproxy.com 
Sent: Thursday, May 30, 2024 11:57 AM
To: 'Tomcat Users List' 
Subject: Write listener question

Hello,

I have a NIO connector with an asynchronous servlet with its write listener.

@Override
  public void onWritePossible() throws IOException {

   if (this.isFirst) {
 this.os = this.asyncContext.getResponse().getOutputStream();
 this.startIdx = 0;
 this.endIdx = WRITE_BUFFER_SIZE;
   }
  
  while (this.startIdx < this.endIdx && this.os.isReady()) {

  this.os.write(this.response, this.startIdx, this.endIdx - this.startIdx);

  this.startIdx = this.endIdx;
  this.endIdx += WRITE_BUFFER_SIZE;
  if (this.endIdx > this.response.length) this.endIdx = 
this.response.length;
   }

   if (this.startIdx == this.endIdx) {
 this.ac.complete();
   }
}

Only when the response to return is bigger than 32K then:
1. Writing the response in chunks of WRITE_BUFFER_SIZE  = 32K, sometimes our 
client receives the response in wrong order (complete, all bytes written, but 
in different order).
2. Setting a WRITE_BUFFER_SIZE  = 8K seems to fix this issue.

But it's weird, this is only happening in this client, we have other 
installations returning responses of megabytes with no issues.

So just a couple of questions:

1. Do you think the implementation of the onWritePossible method above is 
correct?
2. Is it worth to provide a buffered implementation of the ServletOuputStream 
to write the response?


Thanks,

Joan.


-
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



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



Re: PersistentManager and ClassNotFoundException

2024-05-30 Thread Jakub Królikowski
Hi Christopher,

On Thu, May 30, 2024 at 1:40 PM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> Jakub,
>
> On 5/30/24 05:25, Jakub Królikowski wrote:
> >> Where is your  configuration located? It *should* be inside
> >> your  located in META-INF/context.xml in your web application.
> >> If it's in there, then everything it does should be in the context (and
> >> ClassLoader) of your web application -- where your classes should be
> >> locatable.
> >>
> >> If you have it anywhere else, it probably won't work the way you expect
> >> it to work.
> >
> > Yes, you are right! Thank you for this hint!
> > I have configured  in /conf/server.xml.
> > And indeed - interestingly, StandardManager, works correctly even there!
> > PersistentManager, however, does not.
> > After moving the configuration to /META-INF/context.xml, both
> > managers work fine.
> > It may be worth mentioning this in the documentation:
> >
> https://tomcat.apache.org/tomcat-10.1-doc/config/manager.html#Persistence_Across_Restarts
>
> Would you like to provide a documentation patch/PR that works for you?
>
> -chris
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

I can write a paragraph about how to properly prepare the web service for
serialisation and deserialisation, but I need some more time for that,
because I see that the PersistentManager behaves differently from the
StandardManager and I think it tries to serialise also session attributes,
which are not instances of classes that implement java.io.Serializable. I
need more time to experiment.

Jakub


Need help installing SSL certificate in tomcat keystore

2024-05-30 Thread Fung-A-Fat, Mark



I am running a java web app on windows 2019 server and need some help getting 
the SSL certificate installed into my keystore.

I am running tomcat 9.x and java 11

I am able to generate a certificate request using both keytool and/or openssl

For both the CSR file looks like this, but the openssl also generates a private 
key xxx.



-BEGIN NEW CERTIFICATE REQUEST-

MIIC2TCCAcECAQAwZDELMAkGA1UEBhMCdXMxCzAJBgNVBAgTAm1hMRAwDgYDVQQH

-END NEW CERTIFICATE REQUEST-



Private key from OPENSSL

-BEGIN PRIVATE KEY-

MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQC5EqmuGM9nRQ5n

-END PRIVATE KEY-



I use the CSR to submit a request to my company's certificate server and I am 
able to download 2 files in DER format

[cid:image002.png@01DAB26D.E0B15B70]

The downloaded certificate has a name certnew.cer, the downloaded chain 
certificate has a name cernew.p7b and both appear to be binary because when I 
open them in notepad++ they are unreadable

Not sure how I go about importing converting and importing these into my 
keystore using keytool.

The documenation is confusing to me as to what needs to be done.

https://tomcat.apache.org/tomcat-9.0-doc/ssl-howto.html  the section on 
importing the certificate does nto go into how to convert or merge the 
certificate or the certificate chain and also does not say anyting about a 
private keyfile

Has anyone out there done this consistenly and successfully.

Thanks for the help

mark



context.xml file location

2024-05-30 Thread firstName lastName
I am trying to setup JNDI for tomcat with a java webapp. I am using the
official tomcat docker image (version 10.1.24-jdk21-temurin-jammy).
However, I'm a bit confused about where to put the context.xml file. I
tried putting it in /usr/local/tomcat/conf/Catalina/localhost/context.xml
but tomcat refuses to start with the error "The main resource set specified
[/usr/local/tomcat/webapps/context] is not a directory or war file, or is
not readable'. I put my war file in /usr/local/tomcat/webapps/ROOT.war

Are these paths correct or should I have put the context.xml or war file in
a different directory? My hosting provider does not want me to edit the
server.xml file (I have found google articles suggesting defining the JNDI
 tag in the server.xml and then using a  in the
context.xml, but my hosting provider wants me to define the  tag
in the context.xml file instead of the server.xml file).

Thanks for your help!


Re: context.xml file location

2024-05-30 Thread David Rush
I don't know about any docker-related differences, but

I think that if you put a context config file under Catalina/localhost you
need to name the .xml file the same as your .war file.  So if you have
foo.war, then you'd have Catalina/localhost/foo.xml

You can also put a file named context.xml into the .war file itself, under
META-INF directory.

David

On Thu, May 30, 2024 at 7:35 AM firstName lastName 
wrote:

> I am trying to setup JNDI for tomcat with a java webapp. I am using the
> official tomcat docker image (version 10.1.24-jdk21-temurin-jammy).
> However, I'm a bit confused about where to put the context.xml file. I
> tried putting it in /usr/local/tomcat/conf/Catalina/localhost/context.xml
> but tomcat refuses to start with the error "The main resource set specified
> [/usr/local/tomcat/webapps/context] is not a directory or war file, or is
> not readable'. I put my war file in /usr/local/tomcat/webapps/ROOT.war
>
> Are these paths correct or should I have put the context.xml or war file in
> a different directory? My hosting provider does not want me to edit the
> server.xml file (I have found google articles suggesting defining the JNDI
>  tag in the server.xml and then using a  in the
> context.xml, but my hosting provider wants me to define the  tag
> in the context.xml file instead of the server.xml file).
>
> Thanks for your help!
>

-- 

E-Mail to and from me, in connection with the transaction 
of public 
business, is subject to the Wyoming Public Records 
Act and may be 
disclosed to third parties.


Write listener question

2024-05-30 Thread joan.balaguero
Hello,

Sorry for the previous mail ...

I have a NIO connector with an asynchronous servlet with its write listener 
(working in both tomcat 8.5 and tomcat 10.1.20).

@Override
 public void onWritePossible() throws IOException {

  if (this.isFirst) {
this.os = this.asyncContext.getResponse().getOutputStream();
this.startIdx = 0;
this.endIdx = WRITE_BUFFER_SIZE;
  }
 
 while (this.startIdx < this.endIdx && this.os.isReady()) {
 this.os.write(this.response, this.startIdx, this.endIdx - this.startIdx);

 this.startIdx = this.endIdx;
 this.endIdx += WRITE_BUFFER_SIZE;
 if (this.endIdx > this.response.length) this.endIdx = this.response.length;
  }

  if (this.startIdx == this.endIdx) {
this.ac.complete();
  }
}

Only when the response to return is bigger than 32K then:
1. Writing the response in chunks of WRITE_BUFFER_SIZE  = 32K, sometimes our 
client receives the response in wrong order (complete, all bytes written, but 
in different order).
2. Setting a WRITE_BUFFER_SIZE  = 8K seems to fix this issue.

But it's weird, this is only happening in this client, we have other 
installations returning responses of megabytes with no issues.

So just a couple of questions:

1. Do you think the implementation of the onWritePossible method above is 
correct?
2. Is it worth to provide a buffered implementation of the ServletOuputStream 
to write the response?


Thanks,

Joan.




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



Re: context.xml file location

2024-05-30 Thread firstName lastName
Renaming my context.xml to ROOT.xml (without changing the folder) fixed the
problem. Thanks for the help!

On Thu, May 30, 2024 at 8:42 AM David Rush  wrote:

> I don't know about any docker-related differences, but
>
> I think that if you put a context config file under Catalina/localhost you
> need to name the .xml file the same as your .war file.  So if you have
> foo.war, then you'd have Catalina/localhost/foo.xml
>
> You can also put a file named context.xml into the .war file itself, under
> META-INF directory.
>
> David
>
> On Thu, May 30, 2024 at 7:35 AM firstName lastName <
> nouser...@gmail.com>
> wrote:
>
> > I am trying to setup JNDI for tomcat with a java webapp. I am using the
> > official tomcat docker image (version 10.1.24-jdk21-temurin-jammy).
> > However, I'm a bit confused about where to put the context.xml file. I
> > tried putting it in /usr/local/tomcat/conf/Catalina/localhost/context.xml
> > but tomcat refuses to start with the error "The main resource set
> specified
> > [/usr/local/tomcat/webapps/context] is not a directory or war file, or is
> > not readable'. I put my war file in /usr/local/tomcat/webapps/ROOT.war
> >
> > Are these paths correct or should I have put the context.xml or war file
> in
> > a different directory? My hosting provider does not want me to edit the
> > server.xml file (I have found google articles suggesting defining the
> JNDI
> >  tag in the server.xml and then using a  in the
> > context.xml, but my hosting provider wants me to define the 
> tag
> > in the context.xml file instead of the server.xml file).
> >
> > Thanks for your help!
> >
>
> --
>
> E-Mail to and from me, in connection with the transaction
> of public
> business, is subject to the Wyoming Public Records
> Act and may be
> disclosed to third parties.
>


Re: context.xml file location

2024-05-30 Thread Christopher Schultz

Hello,

On 5/30/24 10:12, firstName lastName wrote:

Renaming my context.xml to ROOT.xml (without changing the folder) fixed the
problem. Thanks for the help!


The best practice would be to put your context.xml file into your WAR 
file's META-INF/context.xml path. That way, it will be deployed from the 
WAR file and you don't have to keep a separate file around.


If you need to override the contents of the WAR-packaged file, then you 
will need to use conf/[Engine]/[Host]/[App].xml


https://tomcat.apache.org/tomcat-10.1-doc/config/context.html#Defining_a_context

-chris


On Thu, May 30, 2024 at 8:42 AM David Rush  wrote:


I don't know about any docker-related differences, but

I think that if you put a context config file under Catalina/localhost you
need to name the .xml file the same as your .war file.  So if you have
foo.war, then you'd have Catalina/localhost/foo.xml

You can also put a file named context.xml into the .war file itself, under
META-INF directory.

David

On Thu, May 30, 2024 at 7:35 AM firstName lastName <
nouser...@gmail.com>
wrote:


I am trying to setup JNDI for tomcat with a java webapp. I am using the
official tomcat docker image (version 10.1.24-jdk21-temurin-jammy).
However, I'm a bit confused about where to put the context.xml file. I
tried putting it in /usr/local/tomcat/conf/Catalina/localhost/context.xml
but tomcat refuses to start with the error "The main resource set

specified

[/usr/local/tomcat/webapps/context] is not a directory or war file, or is
not readable'. I put my war file in /usr/local/tomcat/webapps/ROOT.war

Are these paths correct or should I have put the context.xml or war file

in

a different directory? My hosting provider does not want me to edit the
server.xml file (I have found google articles suggesting defining the

JNDI

 tag in the server.xml and then using a  in the
context.xml, but my hosting provider wants me to define the 

tag

in the context.xml file instead of the server.xml file).

Thanks for your help!



--

E-Mail to and from me, in connection with the transaction
of public
business, is subject to the Wyoming Public Records
Act and may be
disclosed to third parties.





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



Re: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-30 Thread Mark Thomas

OK.

This is an interim binary patch for 9.0.80 only.

The purpose is to:
- confirm the proposed change fixes the problem
- provide you with a workaround in the short term

This is the binary patch:

https://people.apache.org/~markt/dev/classloader-not-found-cache-9.0.80-v1.zip

Extract the contents into $CATALINA_HOME/lib

You should end up with:

$CATALINA_HOME/lib/org/apache/...

Usual caveats apply. This is not an official release. Use it at your own 
risk. Don't blame either me or the ASF it is results in alien invasion, 
a tax bill, the server catching fire or anything else unexpected and/or 
unwanted.


Longer term, I'm not sure this is exactly how I want to fix it in 
Tomcat. I am convinced of the need to cache classes that don't exist but 
exactly where / how to do that and what degree of control the user 
should have is very much TBD.


I suspect this will be a topic of discussion at Community Over Code at 
Bratislava next week.


I am expecting that any fix won't be in the June release round but 
should be in the July release round.


Let us know how you get on and good luck.

Mark


On 30/05/2024 10:16, Mark Thomas wrote:

On 29/05/2024 17:03, Eric Robinson wrote:



One of the webapps is related to voice reminder messages that go out 
to people. The reminders go out sometime after 9 am, which tracks with 
the slowdowns.


Ack.

Something to try while I work on a patch is setting 
archiveIndexStrategy="bloom" on the resources.


You'd configure that in META-INF/context.xml something like this:


   


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: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-30 Thread Konstantin Kolinko
ср, 29 мая 2024 г. в 13:34, Mark Thomas :
>
>
>
> It is also problem number 3. The reason it is expensive is that class
> loaders don't cache misses so if a web application has a large number of
> JARs, they all get scanned every time the DriverManager tries to create
> a new connection.
>
>
> The slowness occurs in the web application that depends on the second
> JDBC driver in DriverManager's list. When a request that requires a
> database connection is received, there is a short delay while the web
> application tries, and fails, to load the first JDBC driver in the list.
> Class loading is synchronized on class name being loaded so if any other
> requests also need a database connection, they have to wait for this
> request to finish the search for the JDBC driver before they can
> continue. This creates a bottleneck. Requests are essentially rate
> limited to 1 request that requires a database connection per however
> long it takes to scan every JAR in the web application for a class that
> isn't there. If the average rate of requests exceeds this rate limit
> then a queue is going to build up and it won't subside until the average
> rate of requests falls below this rate limit.
>
> [...]
>
> Problem number 3 is a Tomcat issue. It should be relatively easy to
> start caching misses (i.e. this class loader cannot load this class) and
> save the time spent repeatedly scanning JARs for a class that isn't there.
>

(I wonder if unpacking all JARs into the WEB-INF/classes directory will help.)

> Something to try while I work on a patch is setting
> archiveIndexStrategy="bloom" on the resources.
>
> You'd configure that in META-INF/context.xml something like this:
>
> 
>
> 

+1 for archiveIndexStrategy="bloom".

https://tomcat.apache.org/tomcat-9.0-doc/config/resources.html

The option is available since Tomcat 9.0.69 and thus should be OK here.
(Earlier versions had the feature since 9.0.39, but it was configured
through an attribute of Context
https://bz.apache.org/bugzilla/show_bug.cgi?id=66209

Best regards,
Konstantin Kolinko

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



Re: Write listener question

2024-05-30 Thread Chuck Caldarale


> On May 30, 2024, at 08:47,  
>  wrote:
> 
> I have a NIO connector with an asynchronous servlet with its write listener 
> (working in both tomcat 8.5 and tomcat 10.1.20).
> 
> @Override
> public void onWritePossible() throws IOException {
> 
>  if (this.isFirst) {
>this.os = this.asyncContext.getResponse().getOutputStream();
>this.startIdx = 0;
>this.endIdx = WRITE_BUFFER_SIZE;
>  }


Is there any logic somewhere to clear isFirst? If not, the start and end 
indices will be reset every time this method is called should os.isReady() 
returns false.


> while (this.startIdx < this.endIdx && this.os.isReady()) {
> this.os.write(this.response, this.startIdx, this.endIdx - this.startIdx);
> 
> this.startIdx = this.endIdx;
> this.endIdx += WRITE_BUFFER_SIZE;
> if (this.endIdx > this.response.length) this.endIdx = 
> this.response.length;
>  }
> 
>  if (this.startIdx == this.endIdx) {
>this.ac.complete();
>  }
> }
> 
> Only when the response to return is bigger than 32K then:
> 1. Writing the response in chunks of WRITE_BUFFER_SIZE  = 32K, sometimes our 
> client receives the response in wrong order (complete, all bytes written, but 
> in different order).
> 2. Setting a WRITE_BUFFER_SIZE  = 8K seems to fix this issue.
> 
> But it's weird, this is only happening in this client, we have other 
> installations returning responses of megabytes with no issues.


Perhaps this one client has a slow network, so isReady() returns false in that 
environment, but not in other ones.

  - Chuck


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



RE: Write listener question

2024-05-30 Thread joan.balaguero
Hi Chuck,

isFirst is initialized to 'true' when the class is instantiated, so that
piece of code is just executed the first time the execution enters the '
onWritePossible' method. Later, within the same 'if', 'isFirst' is set to
false, (not shown in the code, sorry)

Perhaps this one client has a slow network, so isReady() returns false in
that environment, but not in other ones.
--> And how can this be solved?  I mean, no one wants to have a piece of
code that works fine just depending on the network speed. The point is the
whole response is returned back (until the last byte), but not in the
correct order. The responses are xml, so some documents cannot be parsed
correctly, that 's why the alert was thrown on the client side.

This is just a sample, but it's like instead of receiving this:


.
...



The client is receiving this:   



...

el>.


It's like a chunk is received in wrong order.

Thanks!

Joan.

-Original Message-
From: Chuck Caldarale  
Sent: Thursday, May 30, 2024 7:27 PM
To: Tomcat Users List 
Subject: Re: Write listener question


> On May 30, 2024, at 08:47, 
 wrote:
> 
> I have a NIO connector with an asynchronous servlet with its write
listener (working in both tomcat 8.5 and tomcat 10.1.20).
> 
> @Override
> public void onWritePossible() throws IOException {
> 
>  if (this.isFirst) {
>this.os = this.asyncContext.getResponse().getOutputStream();
>this.startIdx = 0;
>this.endIdx = WRITE_BUFFER_SIZE;
>  }


Is there any logic somewhere to clear isFirst? If not, the start and end
indices will be reset every time this method is called should os.isReady()
returns false.


> while (this.startIdx < this.endIdx && this.os.isReady()) {
> this.os.write(this.response, this.startIdx, this.endIdx - 
> this.startIdx);
> 
> this.startIdx = this.endIdx;
> this.endIdx += WRITE_BUFFER_SIZE;
> if (this.endIdx > this.response.length) this.endIdx = 
> this.response.length;  }
> 
>  if (this.startIdx == this.endIdx) {
>this.ac.complete();
>  }
> }
> 
> Only when the response to return is bigger than 32K then:
> 1. Writing the response in chunks of WRITE_BUFFER_SIZE  = 32K, sometimes
our client receives the response in wrong order (complete, all bytes
written, but in different order).
> 2. Setting a WRITE_BUFFER_SIZE  = 8K seems to fix this issue.
> 
> But it's weird, this is only happening in this client, we have other
installations returning responses of megabytes with no issues.


Perhaps this one client has a slow network, so isReady() returns false in
that environment, but not in other ones.

  - Chuck


-
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: Write listener question

2024-05-30 Thread Chuck Caldarale


> On May 30, 2024, at 12:53,  
>  wrote:
> 
> isFirst is initialized to 'true' when the class is instantiated, so that
> piece of code is just executed the first time the execution enters the '
> onWritePossible' method. Later, within the same 'if', 'isFirst' is set to
> false, (not shown in the code, sorry)


If you don’t show us all of the code, then it’s rather difficult to answer your 
question about the implementation being correct.


> Perhaps this one client has a slow network, so isReady() returns false in
> that environment, but not in other ones.
> --> And how can this be solved?


The slow network possibility was based on the assumption that isFirst was never 
cleared, since that’s what you presented.

  - Chuck


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



RE: Write listener question

2024-05-30 Thread joan.balaguero
Trying to simplify the code was a mistake ...

private static final int WRITE_BUFFER_SIZE = 8 * 1024;  <-- with 32K fails on 
this client
 
 private final AsyncContext ac;
 private final ServletResponse sr;
 private ServletOutputStream os;
 private boolean firstTime = true;
 private byte[] response;
 private int responseSize, startIdx, endIdx;
 
 // Constructor
 public WriteListenerImpl(AsyncContext ac, byte[] response) {
  this.ac = ac;
  this.sr = this.ac.getResponse();
  this.response = response;
 }
 
 @Override
 public void onWritePossible() throws IOException
 {
   // If this is the first time we call 'onWritePossible' ...
   if (this.firstTime) {
this.firstTime = false;
this.os = this.sr.getOutputStream();

this.responseSize = this.response.length;
this.startIdx = 0;
this.endIdx = Math.min(this.responseSize, WRITE_BUFFER_SIZE);
   }
   
   // And write the 'response'.
   while (this.startIdx < this.endIdx && this.os.isReady()) {
 this.os.write(this.response, this.startIdx, this.endIdx - this.startIdx);

 this.startIdx = this.endIdx;
 this.endIdx += WRITE_BUFFER_SIZE;
 if (this.endIdx > this.responseSize) this.endIdx = this.responseSize;
   }

   // Just perform the 'postProcess' when response writing is finished (start 
== end)
   if (this.startIdx == this.endIdx) {
this.postProcess(null);
   }
 }
 
  @Override
 public void onError(Throwable t) {
  this.postProcess(t);
 }
 
 private void postProcess(Throwable t) {
  this.ac.complete();
  
  if (t != null) {
   t.printStackeTrace();
  }
 }

-Original Message-
From: Chuck Caldarale  
Sent: Thursday, May 30, 2024 8:01 PM
To: Tomcat Users List 
Subject: Re: Write listener question


> On May 30, 2024, at 12:53,  
>  wrote:
> 
> isFirst is initialized to 'true' when the class is instantiated, so 
> that piece of code is just executed the first time the execution enters the '
> onWritePossible' method. Later, within the same 'if', 'isFirst' is set 
> to false, (not shown in the code, sorry)


If you don’t show us all of the code, then it’s rather difficult to answer your 
question about the implementation being correct.


> Perhaps this one client has a slow network, so isReady() returns false 
> in that environment, but not in other ones.
> --> And how can this be solved?


The slow network possibility was based on the assumption that isFirst was never 
cleared, since that’s what you presented.

  - Chuck


-
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: Database Connection Requests Initiated but Not Sent on the Wire (Some, Not All)

2024-05-30 Thread Eric Robinson
Hi Mark,

> -Original Message-
> From: Mark Thomas 
> Sent: Thursday, May 30, 2024 9:30 AM
> To: users@tomcat.apache.org
> Subject: Re: Database Connection Requests Initiated but Not Sent on the Wire
> (Some, Not All)
>
> OK.
>
> This is an interim binary patch for 9.0.80 only.
>
> The purpose is to:
> - confirm the proposed change fixes the problem
> - provide you with a workaround in the short term
>
> This is the binary patch:
>
> https://people.apache.org/~markt/dev/classloader-not-found-cache-9.0.80-
> v1.zip
>
> Extract the contents into $CATALINA_HOME/lib
>
> You should end up with:
>
> $CATALINA_HOME/lib/org/apache/...
>

I'll get on this right away.

> Usual caveats apply. This is not an official release. Use it at your own 
> risk. Don't
> blame either me or the ASF it is results in alien invasion, a tax bill, the 
> server
> catching fire or anything else unexpected and/or unwanted.
>

Okay, but if we're invaded by alien tax collectors riding flaming servers, THEN 
I'm coming after you.

> Longer term, I'm not sure this is exactly how I want to fix it in Tomcat. I am
> convinced of the need to cache classes that don't exist but exactly where / 
> how
> to do that and what degree of control the user should have is very much TBD.
>
> I suspect this will be a topic of discussion at Community Over Code at 
> Bratislava
> next week.
>
> I am expecting that any fix won't be in the June release round but should be 
> in
> the July release round.
>
> Let us know how you get on and good luck.
>

Will do!


> Mark
>
>
> On 30/05/2024 10:16, Mark Thomas wrote:
> > On 29/05/2024 17:03, Eric Robinson wrote:
> >
> > 
> >
> >> One of the webapps is related to voice reminder messages that go out
> >> to people. The reminders go out sometime after 9 am, which tracks
> >> with the slowdowns.
> >
> > Ack.
> >
> > Something to try while I work on a patch is setting
> > archiveIndexStrategy="bloom" on the resources.
> >
> > You'd configure that in META-INF/context.xml something like this:
> >
> > 
> > 
> >
> > 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

Disclaimer : This email and any files transmitted with it are confidential and 
intended solely for intended recipients. If you are not the named addressee you 
should not disseminate, distribute, copy or alter this email. Any views or 
opinions presented in this email are solely those of the author and might not 
represent those of Physician Select Management. Warning: Although Physician 
Select Management has taken reasonable precautions to ensure no viruses are 
present in this email, the company cannot accept responsibility for any loss or 
damage arising from the use of this email or attachments.