You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Daniel Rocha <da...@hotmail.com> on 2016/05/25 15:03:09 UTC

Webapp in the same thread context

Hi,
I have a question related to Tomcat 7.0.69 running in a voyage (debian) system.
I have a java application that was running with "Embedded" class from Tomcat 6.0.Now I am trying to upgrade it to run with Tomcat 7.0.69.
The current java application is initializing some static objects and then starts the "Embedded" class with some Servlets.The Servlets that were initialized access to the static objects from the application that started them. This works fine with Tomcat 6.0.
Now, I am using the "Tomcat" class from Tomcat 7.0 to start the same Servlets.The servlets are initialized and I can access to their context path.
The problem is when I try to access from the Servlet to a static initialized object from the application that started them.The object is null here.
I do not know if this is related to the context class loader.
The code looks something like this:
// Port numberint port = 8080;        // Create an embedded serverthis.embedded = new Tomcat();this.embedded.setBaseDir(getPath());this.embedded.setPort(port);        // Set default virtual hostthis.host = this.embedded.getHost();this.host.setAppBase(getPath() + "/webapps");        // Create the ROOT contextthis.rootcontext = this.embedded.addWebapp(this.host, "", getPath() + "/webapps/ROOT");this.rootcontext.setReloadable(false);this.rootcontext.addWelcomeFile("index.jsp");        // Create servlet contextthis.rootcontext = this.embedded.addWebapp(this.host, "/context", "/home/path/to/app");this.rootcontext.setReloadable(false);context.setPrivileged(true);
// Set connector propertiesConnector connector = this.embedded.getConnector();connector.setSecure(false);connector.setProperty("maxThreads", "10");connector.setProperty("acceptCount", "20");connector.setProperty("asyncTimeout", "30000");connector.setProperty("connectionTimeout", "30000");connector.setProperty("socket.soTimeout", "30000");connector.setEnableLookups(false);this.embedded.setConnector(connector);        // Start the embedded serverthis.embedded.start();

Can you please help me with this question?
Best regards,Daniel Rocha 		 	   		  

RE: Webapp in the same thread context

Posted by Daniel Rocha <da...@hotmail.com>.
Hi,
Thanks again for replying and thanks for the advice. Yes, you are right.
I was able to put it work with the structure that I had in Tomcat 6.0.I just had to edit the "context.xml" from each servlet and add the following element inside the Context:    <Loader delegate="true"/> 
This property makes the web application class loader change its order:https://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html

Thanks again,Best regards,Daniel Rocha

> Subject: Re: Webapp in the same thread context
> To: users@tomcat.apache.org
> From: chris@christopherschultz.net
> Date: Fri, 27 May 2016 09:33:46 -0400
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
> 
> Daniel,
> 
> On 5/27/16 4:53 AM, Daniel Rocha wrote:
> > The application that starts the servlets and initializes the
> > static objects:/home/project/lib/app.jar The tomcat temporary
> > folder "this.embedded.setBaseDir(getPath());" is located 
> > under:/home/project/temp_tomcat/ The servlets are located 
> > under:/home/project/webapps/servletname/ In the "servletname" 
> > directory I have what the compiler (I am using Netbeans as the
> > IDE) generates under build/web directory. This means I have the
> > WEB-INF, META-INF and the web pages inside the directory. The
> > .class are inside the WEB-INF.
> > 
> > Under the WEB-INF/lib of the servlets directory I have the
> > "app.jar" in each of them.
> > 
> > So, I tried to do something and it worked.
> > 
> > I put the "app.jar" inside the tomcat temporary folder 
> > "/home/project/temp_tomcat/lib" (as a shared library) and I
> > deleted the "app.jar" from each servlet (WEB-INF/lib/app.jar) and
> > it worked.
> > 
> > Can you please explain to me what really happened to start
> > working? Is there another way (some tomcat option) to do this
> > without having to put the "app.jar" inside the tomcat temporary
> > folder?
> 
> You app.jar contains both the classes required to boot the enbedded
> system *and* the classes that run your web applications?
> 
> If you have the web application classes referring to the "main app"
> classes (specifically, fetching a static value), then you will always
> have this problem.
> 
> I recommend splitting your application into separate JAR files: one for
> the launcher and a second one for the web application. You might even
> want another one for the shared stuff. The launcher can live on its own,
> the shared-library can live in Tomcat's lib/ directory, and the webapp
> JAR can be in the WEB-INF/lib directory of the application.
> 
> Any other layout will cause problems, unless you are okay with the
> application being one big JAR (app.jar) in Tomcat's lib/ directory.
> 
> The reason for this is how Java defines classes at runtime. A
> (capital-C) Class is defined by the fully-qualified class name (e.g.
> foo.bar.MyClass) *plus* the ClassLoader that loaded it. So if you have a
> class available in different ClassLoaders (e.g. in both the webapp
> ClassLoader and the shared ClassLoader), then objects of those two
> Classes aren't always compatible with each other. The webapp ClassLoader
> is defined to perform a local-load *first*, then delegate to the parent.
> In the usual delegate-first class loading model, this issue wouldn't
> happen because the parent loader would always be preferred.
> 
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Comment: GPGTools - http://gpgtools.org
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
> 
> iQIcBAEBCAAGBQJXSEy6AAoJEBzwKT+lPKRYa7MQAKbsGpfWP4lVUU0d16fFACi1
> LCPj1Es9s/Z/i3bWvClyqIjzIgI8t016nLp7i444cXR2xl2rUgEy9KLbRryyV7qI
> 4H91dbb9Xvef/hYesq/T1FWK30VfkQAnQrDqdtoht9pKyYbXFhn8HUr+hBYIkxUb
> GOfT/Ge7zgekYBx+hhEtDzsXTFL0b/FGMDLAYAAq+qQbfjJEiFuA5iG4/3hrQAUa
> LtkmS1NDWoNSxyey4AijpomdCUrY1IrrloZayGQF+p/1Vi2Xq6gt6vEsheP+Go7M
> if7ub2SA47moIXUSRvPj73IK/88/OBbMbWxzA9WXkriH7fa5ZeDa1jJDrKzVk9Tx
> aPsqOcHrzc7RbkoJhOU9v8tXmdmTtlM+dWqpS/PPqxS/d7xWf+irzkKy+nWI1wau
> xWNgt7uT6TG0N/sdPC0fSBujwlyz8RRndVyVIKGHTvUr4lWK8ec8YidKdaimaJyy
> MmAGoZIgRUs1uP+bctBoIJN+PV+0AzXBdSu2Xqd4S5q6sfWMEM1f4p9Kg0ezewg8
> puyHKdzctkdEdJDDE5oWLZh9j2lj66u9OcjgXbEF1pjMjQyfNZI2fkTzLArAqkeV
> JjDOJ0S6Avn4u1gEL8QmOLOZlnO18HI7bWBhsXUVDQZh+MAgtHFNlxkW5SXy4M5F
> CBUlKxFop9HdAwEfRDjq
> =vuj5
> -----END PGP SIGNATURE-----
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
 		 	   		  

Re: Webapp in the same thread context

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Daniel,

On 5/27/16 4:53 AM, Daniel Rocha wrote:
> The application that starts the servlets and initializes the
> static objects:/home/project/lib/app.jar The tomcat temporary
> folder "this.embedded.setBaseDir(getPath());" is located 
> under:/home/project/temp_tomcat/ The servlets are located 
> under:/home/project/webapps/servletname/ In the "servletname" 
> directory I have what the compiler (I am using Netbeans as the
> IDE) generates under build/web directory. This means I have the
> WEB-INF, META-INF and the web pages inside the directory. The
> .class are inside the WEB-INF.
> 
> Under the WEB-INF/lib of the servlets directory I have the
> "app.jar" in each of them.
> 
> So, I tried to do something and it worked.
> 
> I put the "app.jar" inside the tomcat temporary folder 
> "/home/project/temp_tomcat/lib" (as a shared library) and I
> deleted the "app.jar" from each servlet (WEB-INF/lib/app.jar) and
> it worked.
> 
> Can you please explain to me what really happened to start
> working? Is there another way (some tomcat option) to do this
> without having to put the "app.jar" inside the tomcat temporary
> folder?

You app.jar contains both the classes required to boot the enbedded
system *and* the classes that run your web applications?

If you have the web application classes referring to the "main app"
classes (specifically, fetching a static value), then you will always
have this problem.

I recommend splitting your application into separate JAR files: one for
the launcher and a second one for the web application. You might even
want another one for the shared stuff. The launcher can live on its own,
the shared-library can live in Tomcat's lib/ directory, and the webapp
JAR can be in the WEB-INF/lib directory of the application.

Any other layout will cause problems, unless you are okay with the
application being one big JAR (app.jar) in Tomcat's lib/ directory.

The reason for this is how Java defines classes at runtime. A
(capital-C) Class is defined by the fully-qualified class name (e.g.
foo.bar.MyClass) *plus* the ClassLoader that loaded it. So if you have a
class available in different ClassLoaders (e.g. in both the webapp
ClassLoader and the shared ClassLoader), then objects of those two
Classes aren't always compatible with each other. The webapp ClassLoader
is defined to perform a local-load *first*, then delegate to the parent.
In the usual delegate-first class loading model, this issue wouldn't
happen because the parent loader would always be preferred.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJXSEy6AAoJEBzwKT+lPKRYa7MQAKbsGpfWP4lVUU0d16fFACi1
LCPj1Es9s/Z/i3bWvClyqIjzIgI8t016nLp7i444cXR2xl2rUgEy9KLbRryyV7qI
4H91dbb9Xvef/hYesq/T1FWK30VfkQAnQrDqdtoht9pKyYbXFhn8HUr+hBYIkxUb
GOfT/Ge7zgekYBx+hhEtDzsXTFL0b/FGMDLAYAAq+qQbfjJEiFuA5iG4/3hrQAUa
LtkmS1NDWoNSxyey4AijpomdCUrY1IrrloZayGQF+p/1Vi2Xq6gt6vEsheP+Go7M
if7ub2SA47moIXUSRvPj73IK/88/OBbMbWxzA9WXkriH7fa5ZeDa1jJDrKzVk9Tx
aPsqOcHrzc7RbkoJhOU9v8tXmdmTtlM+dWqpS/PPqxS/d7xWf+irzkKy+nWI1wau
xWNgt7uT6TG0N/sdPC0fSBujwlyz8RRndVyVIKGHTvUr4lWK8ec8YidKdaimaJyy
MmAGoZIgRUs1uP+bctBoIJN+PV+0AzXBdSu2Xqd4S5q6sfWMEM1f4p9Kg0ezewg8
puyHKdzctkdEdJDDE5oWLZh9j2lj66u9OcjgXbEF1pjMjQyfNZI2fkTzLArAqkeV
JjDOJ0S6Avn4u1gEL8QmOLOZlnO18HI7bWBhsXUVDQZh+MAgtHFNlxkW5SXy4M5F
CBUlKxFop9HdAwEfRDjq
=vuj5
-----END PGP SIGNATURE-----

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


RE: Webapp in the same thread context

Posted by Daniel Rocha <da...@hotmail.com>.
Hi,
Thanks for replying.
I have the following structure:
The application that starts the servlets and initializes the static objects:/home/project/lib/app.jar
The tomcat temporary folder "this.embedded.setBaseDir(getPath());" is located under:/home/project/temp_tomcat/
The servlets are located under:/home/project/webapps/servletname/
In the "servletname" directory I have what the compiler (I am using Netbeans as the IDE) generates under build/web directory. This means I have the WEB-INF, META-INF and the web pages inside the directory. The .class are inside the WEB-INF.
Under the WEB-INF/lib of the servlets directory I have the "app.jar" in each of them.
So, I tried to do something and it worked.
I put the "app.jar" inside the tomcat temporary folder "/home/project/temp_tomcat/lib" (as a shared library) and I deleted the "app.jar" from each servlet (WEB-INF/lib/app.jar) and it worked.

Can you please explain to me what really happened to start working?Is there another way (some tomcat option) to do this without having to put the "app.jar" inside the tomcat temporary folder? 

Thank you in advance,Best regards,Daniel Rocha

> Subject: Re: Webapp in the same thread context
> To: users@tomcat.apache.org
> From: chris@christopherschultz.net
> Date: Wed, 25 May 2016 14:19:22 -0400
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
> 
> Daniel,
> 
> On 5/25/16 11:03 AM, Daniel Rocha wrote:
> > I have a java application that was running with "Embedded" class 
> > from Tomcat 6.0.Now I am trying to upgrade it to run with Tomcat 
> > 7.0.69.
> > 
> > The current java application is initializing some static objects 
> > and then starts the "Embedded" class with some Servlets.The 
> > Servlets that were initialized access to the static objects from 
> > the application that started them. This works fine with Tomcat 
> > 6.0.
> > 
> > Now, I am using the "Tomcat" class from Tomcat 7.0 to start the 
> > same Servlets.The servlets are initialized and I can access to 
> > their context path.
> > 
> > The problem is when I try to access from the Servlet to a static 
> > initialized object from the application that started them.The 
> > object is null here.
> 
> Where is the .class file located for the servlet? Where is the .class
> file located for the "static initialized object" reference? You need
> to be very specific about what's going on, here, because lack of
> precision can cause all kinds of missteps.
> 
> > I do not know if this is related to the context class loader.
> 
> It's almost certainly related to the ClassLoader... probably the
> WebappClassLoader.
> 
> > The code looks something like this:
> > 
> > // Port number int port = 8080; // Create an embedded
> > serverthis.embedded = new Tomcat(); 
> > this.embedded.setBaseDir(getPath()); this.embedded.setPort(port); 
> > // Set default virtual hostthis.host = this.embedded.getHost(); 
> > this.host.setAppBase(getPath() + "/webapps"); // Create the ROOT
> > contextthis.rootcontext = this.embedded.addWebapp(this.host, "",
> > getPath() + "/webapps/ROOT"); 
> > this.rootcontext.setReloadable(false); 
> > this.rootcontext.addWelcomeFile("index.jsp"); // Create servlet
> > context this.rootcontext = this.embedded.addWebapp(this.host,
> > "/context",
> "/home/path/to/app");
> > this.rootcontext.setReloadable(false);context.setPrivileged(true);
> > 
> > // Set connector propertiesConnector connector =
> > this.embedded.getConnector(); connector.setSecure(false); 
> > connector.setProperty("maxThreads", "10"); 
> > connector.setProperty("acceptCount", "20"); 
> > connector.setProperty("asyncTimeout", "30000"); 
> > connector.setProperty("connectionTimeout", "30000"); 
> > connector.setProperty("socket.soTimeout", "30000"); 
> > connector.setEnableLookups(false);
> > 
> > this.embedded.setConnector(connector); // Start the embedded
> > server this.embedded.start();
> 
> There is nothing in that code that is going to cause any problem like
> you describe. Tell us how the code that fails interacts with the code
> that is (likely) loaded from the wrong ClassLoader.
> 
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Comment: GPGTools - http://gpgtools.org
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
> 
> iQIcBAEBCAAGBQJXReyqAAoJEBzwKT+lPKRYyREP/iFMdNtenVwqDSw3u7senlVs
> UUQ4QrdiHa1CYtl3DZMNnxq47EnK8oKbHEsR4ELN4K1fJ2MzDC+gCL33AhFF8b1+
> bNRczRdj9aq3SbHqWR7Cb06CRj3qZ6FKexlHaHVgAVBuo0o7+Vp1+P843qWjDLCt
> ZrWQ9gdsMI/9spKXn11QnP/q0yW3SiMoTOTTob5ByEKfhZMFupuhCBZnhqQC2fZh
> D0iivElIaJer4Q5OXDblo4lBfwFSJtT2Xlkqx4B2xMNVf1obrYai4tGlXNtXVlwI
> wgsLvmaRT9tOCf/6uSnuTNKlxX5P3FKQYbyecsYUCmHysJ+f6kGIxY3PdwuL4Arq
> 4OlyfsYX6wDtcHGEw+T9gtG+Z+QQw1RKLwtYv6sasEjQIusVNJGwZbsWgi+TYNS5
> C2Ini934fDWJwc9DljEjvr3cYQMEt5ysMKNMVAG0d4SLsL9ug1iBiuv/ZH4LcG0m
> +PWq6kGOmlpUHq/j7ySvKadg/YvXzr5OTagr7hCn88Z3WU0K+oJcKgE9QA9qDHGc
> 9a+ZyNFRbdfh4yW5zmCbK+0EYH6BZ9mjKU/tOVjjaiqEU/AJOb9itLVHXz6yek5e
> LlHXomL1w1tJGQ9zYiJx3/oBHC1px05n0hqfKKkfbRjsUI44Mjuyqo0SpymWxQi/
> XuI+yXCgM4Vi7h4mcGFc
> =jHSA
> -----END PGP SIGNATURE-----
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
 		 	   		  

Re: Webapp in the same thread context

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Daniel,

On 5/25/16 11:03 AM, Daniel Rocha wrote:
> I have a java application that was running with "Embedded" class 
> from Tomcat 6.0.Now I am trying to upgrade it to run with Tomcat 
> 7.0.69.
> 
> The current java application is initializing some static objects 
> and then starts the "Embedded" class with some Servlets.The 
> Servlets that were initialized access to the static objects from 
> the application that started them. This works fine with Tomcat 
> 6.0.
> 
> Now, I am using the "Tomcat" class from Tomcat 7.0 to start the 
> same Servlets.The servlets are initialized and I can access to 
> their context path.
> 
> The problem is when I try to access from the Servlet to a static 
> initialized object from the application that started them.The 
> object is null here.

Where is the .class file located for the servlet? Where is the .class
file located for the "static initialized object" reference? You need
to be very specific about what's going on, here, because lack of
precision can cause all kinds of missteps.

> I do not know if this is related to the context class loader.

It's almost certainly related to the ClassLoader... probably the
WebappClassLoader.

> The code looks something like this:
> 
> // Port number int port = 8080; // Create an embedded
> serverthis.embedded = new Tomcat(); 
> this.embedded.setBaseDir(getPath()); this.embedded.setPort(port); 
> // Set default virtual hostthis.host = this.embedded.getHost(); 
> this.host.setAppBase(getPath() + "/webapps"); // Create the ROOT
> contextthis.rootcontext = this.embedded.addWebapp(this.host, "",
> getPath() + "/webapps/ROOT"); 
> this.rootcontext.setReloadable(false); 
> this.rootcontext.addWelcomeFile("index.jsp"); // Create servlet
> context this.rootcontext = this.embedded.addWebapp(this.host,
> "/context",
"/home/path/to/app");
> this.rootcontext.setReloadable(false);context.setPrivileged(true);
> 
> // Set connector propertiesConnector connector =
> this.embedded.getConnector(); connector.setSecure(false); 
> connector.setProperty("maxThreads", "10"); 
> connector.setProperty("acceptCount", "20"); 
> connector.setProperty("asyncTimeout", "30000"); 
> connector.setProperty("connectionTimeout", "30000"); 
> connector.setProperty("socket.soTimeout", "30000"); 
> connector.setEnableLookups(false);
> 
> this.embedded.setConnector(connector); // Start the embedded
> server this.embedded.start();

There is nothing in that code that is going to cause any problem like
you describe. Tell us how the code that fails interacts with the code
that is (likely) loaded from the wrong ClassLoader.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJXReyqAAoJEBzwKT+lPKRYyREP/iFMdNtenVwqDSw3u7senlVs
UUQ4QrdiHa1CYtl3DZMNnxq47EnK8oKbHEsR4ELN4K1fJ2MzDC+gCL33AhFF8b1+
bNRczRdj9aq3SbHqWR7Cb06CRj3qZ6FKexlHaHVgAVBuo0o7+Vp1+P843qWjDLCt
ZrWQ9gdsMI/9spKXn11QnP/q0yW3SiMoTOTTob5ByEKfhZMFupuhCBZnhqQC2fZh
D0iivElIaJer4Q5OXDblo4lBfwFSJtT2Xlkqx4B2xMNVf1obrYai4tGlXNtXVlwI
wgsLvmaRT9tOCf/6uSnuTNKlxX5P3FKQYbyecsYUCmHysJ+f6kGIxY3PdwuL4Arq
4OlyfsYX6wDtcHGEw+T9gtG+Z+QQw1RKLwtYv6sasEjQIusVNJGwZbsWgi+TYNS5
C2Ini934fDWJwc9DljEjvr3cYQMEt5ysMKNMVAG0d4SLsL9ug1iBiuv/ZH4LcG0m
+PWq6kGOmlpUHq/j7ySvKadg/YvXzr5OTagr7hCn88Z3WU0K+oJcKgE9QA9qDHGc
9a+ZyNFRbdfh4yW5zmCbK+0EYH6BZ9mjKU/tOVjjaiqEU/AJOb9itLVHXz6yek5e
LlHXomL1w1tJGQ9zYiJx3/oBHC1px05n0hqfKKkfbRjsUI44Mjuyqo0SpymWxQi/
XuI+yXCgM4Vi7h4mcGFc
=jHSA
-----END PGP SIGNATURE-----

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