Re: o.a.c.startup.WebappServiceLoader.load inconsistent behavior when searching for SCI (different loaders when searching for container SCIs)

2015-03-18 Thread Violeta Georgieva
Hi,

2015-03-18 11:35 GMT+02:00 Mark Thomas :
>
> On 18/03/2015 09:00, Violeta Georgieva wrote:
> > Hi,
> >
> > I have an issue that I investigate and it led me to the implementation
> > of org.apache.catalina.startup.WebappServiceLoader.load(Class)
> >
> > So I have two scenarios:
> > - web application with web fragment inside the archive (WEB-INF/lib)
> > - web application with functionality of the fragment copied directly to
the
> > WEB-INF classes i.e. there is no web fragment.
> >
> > In the first scenario we (WebappServiceLoader.load) will search for
SCIs in
> > the web fragment using web app loader and then on row 121 we will
switch to
> > the paren loader and then continue searching the SCIs in other
locations.
> > In the second scenario we will search for SCIs always with the web app
> > loader.
> >
> > The problem that I'm investigating is in OSGi environment where the
parent
> > loader of the web app loader does not mean the same as in non OSGi
> > environment. When there is no web fragment I can find the container SCIs
> > (e.g. Web Socket implementation), but when there is web fragment I
cannot
> > find the SCIs anymore because of the switch of the loaders.
> >
> > Can you give me an advice how to overcome this issue?
> > I'm trying to use as much as possible from Tomcat implementation and to
> > plug only here and there in order to support OSGi environment.
>
> Hmm. Either we find a way to patch the WebappServiceLoader so it works
> with non-OSGI and OSGI environments or it looks like you'd have to use a
> custom ContextConfig implementation that used a different
> WebappServiceLoader.
>
> I've no objections to considering patching - with the usual caveats
> about the final decision coming down to what the actual patch looks like.
>
> If I have understood you correctly, the problematic line is:
> loader = loader.getParent()
>
> In the non-OSGI case loader.getParent() is the shared class loader (the
> Tomcat 5.5 class loader docs [1] are probably the better ones to look at
> in this case as it shows the full hierarchy which was collapsed in later
> versions).
>
> If this line was changed to:
> loader = context.getParentClassLoader()

I tried with quick patches in Tomcat and on my side and with one very basic
scenario and it is working.

I'll test a little bit more but at the moment this is the change that I
made in WebappServiceLoader (based on Tomcat 7 trunk):


Index: java/org/apache/catalina/startup/ContextConfig.java
===
--- java/org/apache/catalina/startup/ContextConfig.java (revision 1667469)
+++ java/org/apache/catalina/startup/ContextConfig.java (working copy)
@@ -1278,7 +1278,7 @@

 // Step 3. Look for ServletContainerInitializer implementations
 if (ok) {
-
 processServletContainerInitializers(context.getServletContext());
+processServletContainerInitializers();
 }

 if  (!webXml.isMetadataComplete() || typeInitializerMap.size() >
0) {
@@ -1567,13 +1567,13 @@
 /**
  * Scan JARs for ServletContainerInitializer implementations.
  */
-protected void processServletContainerInitializers(ServletContext
servletContext) {
+protected void processServletContainerInitializers() {

 List detectedScis;
 try {
 WebappServiceLoader loader =
 new WebappServiceLoader(
-servletContext,
context.getContainerSciFilter());
+context, context.getContainerSciFilter());
 detectedScis = loader.load(ServletContainerInitializer.class);
 } catch (IOException e) {
 log.error(sm.getString(
Index: java/org/apache/catalina/startup/WebappServiceLoader.java
===
--- java/org/apache/catalina/startup/WebappServiceLoader.java (revision
1667469)
+++ java/org/apache/catalina/startup/WebappServiceLoader.java (working copy)
@@ -33,6 +33,8 @@

 import javax.servlet.ServletContext;

+import org.apache.catalina.Context;
+
 /**
  * A variation of Java's JAR ServiceLoader that respects exclusion rules
for
  * web applications.
@@ -57,7 +59,8 @@
 private static final String SERVICES = "META-INF/services/";
 private static final Charset UTF8 = Charset.forName("UTF-8");

-private final ServletContext context;
+private final ServletContext servletContext;
+private final Context context;
 private final Pattern containerSciFilterPattern;

 /**
@@ -65,8 +68,9 @@
  *
  * @param context the context to use
  */
-public WebappServiceLoader(ServletContext context, String
containerSciFilter) {
+public WebappServiceLoader(Context context, String containerSciFilter)
{
 this.context = context;
+this.servletContext = context.getServletContext();
 if (containerSciFilter != null && containerSciFilter.length() > 0)
{
 containerSciFilterPattern =
P

Re: o.a.c.startup.WebappServiceLoader.load inconsistent behavior when searching for SCI (different loaders when searching for container SCIs)

2015-03-18 Thread Mark Thomas
On 18/03/2015 09:00, Violeta Georgieva wrote:
> Hi,
> 
> I have an issue that I investigate and it led me to the implementation
> of org.apache.catalina.startup.WebappServiceLoader.load(Class)
> 
> So I have two scenarios:
> - web application with web fragment inside the archive (WEB-INF/lib)
> - web application with functionality of the fragment copied directly to the
> WEB-INF classes i.e. there is no web fragment.
> 
> In the first scenario we (WebappServiceLoader.load) will search for SCIs in
> the web fragment using web app loader and then on row 121 we will switch to
> the paren loader and then continue searching the SCIs in other locations.
> In the second scenario we will search for SCIs always with the web app
> loader.
> 
> The problem that I'm investigating is in OSGi environment where the parent
> loader of the web app loader does not mean the same as in non OSGi
> environment. When there is no web fragment I can find the container SCIs
> (e.g. Web Socket implementation), but when there is web fragment I cannot
> find the SCIs anymore because of the switch of the loaders.
> 
> Can you give me an advice how to overcome this issue?
> I'm trying to use as much as possible from Tomcat implementation and to
> plug only here and there in order to support OSGi environment.

Hmm. Either we find a way to patch the WebappServiceLoader so it works
with non-OSGI and OSGI environments or it looks like you'd have to use a
custom ContextConfig implementation that used a different
WebappServiceLoader.

I've no objections to considering patching - with the usual caveats
about the final decision coming down to what the actual patch looks like.

If I have understood you correctly, the problematic line is:
loader = loader.getParent()

In the non-OSGI case loader.getParent() is the shared class loader (the
Tomcat 5.5 class loader docs [1] are probably the better ones to look at
in this case as it shows the full hierarchy which was collapsed in later
versions).

If this line was changed to:
loader = context.getParentClassLoader()

it would have the same effect for non-OSGI. Would it help in OSGI?

If this doesn't help, would something along similar lines help? If so, what?

Mark
(who knows next to nothing about class loading in OSGI environments)


[1] http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html

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



o.a.c.startup.WebappServiceLoader.load inconsistent behavior when searching for SCI (different loaders when searching for container SCIs)

2015-03-18 Thread Violeta Georgieva
Hi,

I have an issue that I investigate and it led me to the implementation
of org.apache.catalina.startup.WebappServiceLoader.load(Class)

So I have two scenarios:
- web application with web fragment inside the archive (WEB-INF/lib)
- web application with functionality of the fragment copied directly to the
WEB-INF classes i.e. there is no web fragment.

In the first scenario we (WebappServiceLoader.load) will search for SCIs in
the web fragment using web app loader and then on row 121 we will switch to
the paren loader and then continue searching the SCIs in other locations.
In the second scenario we will search for SCIs always with the web app
loader.

The problem that I'm investigating is in OSGi environment where the parent
loader of the web app loader does not mean the same as in non OSGi
environment. When there is no web fragment I can find the container SCIs
(e.g. Web Socket implementation), but when there is web fragment I cannot
find the SCIs anymore because of the switch of the loaders.

Can you give me an advice how to overcome this issue?
I'm trying to use as much as possible from Tomcat implementation and to
plug only here and there in order to support OSGi environment.

I'm debugging with sources from Tomcat 7 trunk.

Regards,
Violeta