Hello! See my comments inline
niedz., 15 lis 2020 o 08:15 'paul stanley' via OPS4J
<[email protected] <mailto:[email protected]>> napisał(a):
Hello,
My initial issue was that pure JAXRS WABs fail to bootstrap karaf,
where as they work as documented when deployed into the OSGi side of
Glassfish.Glassfish may be a JakartaEE platform, but essentiality it
is an OSGI framework running on Felix. Therefore, felix should also
support the concept of dropping annotated applications into the
framework that will be picked up and initialised by the relevant
extender.
"Glassfish may be a JakartaEE platform, but essentiality it is an OSGI
framework running on Felix" - IMO this statement is wrong. OSGi is an
implementation detail of Glassfish and not its deployment/programming
model. Superior programming/deployment model is JavaEE and it has to be
JavaEE compliant (as it's RI).
So the fact that pure JAXRS WAB failed is Karaf or Pax-Web (or any other
WAB extender you've added to Karaf) fault and not that Glassfish did
something right.
This process is complicated by the fact that JAXRS services are web
applications that are bootstrapped by a method described in the
Servlet 3 specification.This is achieved by the appropriate
technology (i.e. CXF or Jersey) providing a
ServletContainerInitializer that allows the service to examine
application and decided if further action is required.
And that's what I'm carefully tackling in Pax Web 8, master-improvements
branch. ServietContainerInitializers were not implemented correctly in
Pax Web 7 wrt to classloading.
As discussed previously the ServletContainerInitializer's are
discovered through the use of the Java Util ServiceLoader
service.This means that the META-INF/services file needs to be
visible and creatable by the application's class loader.Or via some
other means, e.g. servlet, jsp and jsf implementations are supported
by the pax-web-extender specifically wiring in the appropriate class
loaders during the web context initialisation process.
And in OSGi, being networking and not hierarchical classloader system
needs to handle SCIs differently - we can't search entire network of
classloaders, while it's easy with hierarchical model.
As such I've been trying to understand how Glassfish achieved
something similar in a felix container, without the need for the
application to specify either the Jersey implementation or the
auxiliary library that contained the SCI.
As I've said - Felix is implementation detail and when you deploy a WAR
into Glassfish, this WAR is not even aware that there's Felix/OSGi
underneath. There's strict and well-defined classloader passed to
ServetContext implementation being associated with the WAR and
everything just works according to JavaEE.
It turns out that GF is using a couple of tricks to construct a
common classloader at runtime which contains dependencies on all
bundles that offer services through the ServiceLoader framework.This
is then used as the parent classloader when bootstrapping web and
other types of services, thus decoupling the web framework
implementation from the applications that use it.
Exactly. But this doesn't mean that any bundle that you sneak into this
Felix-under-Glassfish will be used as the bundle providing extensions to
how SCIs are handled when you deploy a WAR into Glassfish ;)
Personally I like this approach as it allows our framework engineer
to maintain the platforms separately from application developers who
only need be concerned with the business logic.Thus if we want to
upgrade or change the implementation of a particular technology
(e.g. JAXRS, Spring, JPA, XML/JSON Binding, etc…) then we can
without the need to rebuild all of the applications that use it.
That's rather a promise of JavaEE and it's not that easy with OSGi. I
mean OSGi's promise to replace impl without changing API is even
stronger, because it works at package level, not at API level (though
OSGi "contracts" are supposed to move this up from package to
set-of-packages level).
As a demo I have extended the ServletContainerInitializerScanner in
the pax-web-api to track bundles that provide the SCI via the
service loader file.These are then returned to the
JettyServerWrapper when it is creating the HttpServiceContext.The
result is that JAXRS, WebSocket and Spring MVC applications are all
correctly initialised without the need to hard code a specific
implementation into the business logic bundles.
Cool! That's a proof that original scanner in Pax Web 7 didn't work
correctly. I'm working on this in Pax Web 8.
I realise that bootstrapping services like this does not conform to
the class loading concepts of the OSGI specification, however it
does make Karaf more flexible when used as a service platform.As
such, I believe that we should consider adding the option of a SCI
Bundle Extender to the pax web offering.
I'll try to make it as configurable as possible in Pax Web 8 - feel free
to review master-improvements branch before it gets merged into master!
regards
Grzegorz Grzybek
Regards
Paul
On Friday, November 6, 2020 at 1:48:44 PM UTC [email protected]
<mailto:[email protected]> wrote:
Hello!
pt., 6 lis 2020 o 14:44 'paul stanley' via OPS4J
<[email protected]> napisał(a):
Thanks Grzegorz,
I'll have a more detailed look at this when I get back next
week.
Sure! Looking forward to your findings ;)
regards
Grzegorz Grzybek
Regards
Paul
On 2 Nov 2020, at 06:22, Grzegorz Grzybek
<[email protected]> wrote:
Hello
niedz., 1 lis 2020 o 18:56 'paul stanley' via OPS4J <
[email protected]> napisał(a):
Hi Grzegorz,
Sorry about the delay in getting back to you.
I realise your concerns about sci's from different
webapps interfering with each other. However the SCI
mechanism appears to be the way that the other web
technologies, such as JAXRS and SpringMVC have a
chance to detect and influence the creation of the
servlet.
JaxRS and SpringMVC were designed to work in JavaEE
runtime (or just flat classpath for non servlet
applications) which has well defined hierarchical
ClassLoader model, so scanning for SCIs is easy - just
start with current ClassLoader (assigned to the WAR for
example) and walk through parents.
OSGi has also (very) well defined ClassLoader model -
but it's not hierarchical, it's _network_ bidirectional
graph of ClassLoaders...
Given that ServiceLoader architecture is being used,
is it unreasonable that all possible instances for
the SCI get asked to look at the bundle and
initialize the context is appropriate?
Hmm, I'm not sure I understand... SCI in onStartup()
gets an instance of ServletContext and array of classes
- it should not be bundle aware...
If not, then we need another way to extend the
WebExtender with other web frameworks, allowing them
to get involved with servlet creation. Which does
not include altering the webapp in some OSGI
specific way.
I'm not sure we can extend the WebExtender (quite low
level framework) with some web framework (SpringMVC,
JaxRS, Wicket, Tapestry, name it - all more high level)....
But fear not - the best way to detect proper SCIs (IMO)
is simply to use WAB archives, so all jars from
Bundle-ClassPath manifest header (which by default means
all jars from /WEB-INF/lib of the bundle) are scanned
for SCIs and web-fragment.xmls.
regards
Grzegorz Grzybek
Cheers
Paul
On 30 Oct 2020, at 08:46, Grzegorz Grzybek <
[email protected]> wrote:
Hello
czw., 29 paź 2020 o 19:50 Matt Pavlovich <
[email protected]> napisał(a):
Paul--
You might checkout a BundleTracker. A
BundleTracker is ensured to get a callback
for every bundle, regardless as to when your
bundle started. With a BundleListener, there
is a race condition that you may not be
activated before some bundles that you care
about.
It's not about bundle tracker or listener.
Whiteboard implementation uses such tracker to
ensure that when a bundle is gone, all
associated contexts and web elements should be
deregistered.
It's more about which bundles should be scanned
for ServletContainerInitializers. imagine you
install two "sets" of bundles (e.g., Karaf
features) - you don't want SCIs from one feature
(web application) to be used in another
feature/web application...
regards
Grzegorz Grzybek
ref:
https://docs.osgi.org/specification/osgi.core/7.0.0/util.tracker.html#d0e52020
<https://docs.osgi.org/specification/osgi.core/7.0.0/util.tracker.html#d0e52020>
-Matt
On Thursday, October 29, 2020 at 1:17:19 PM
UTC-5 [email protected] wrote:
Thanks Grzegorz. I know what you mean
about doing my "normal job", I also have
be careful as to what can be shared to
the community.
I realise that the ServiceLoader is a
bit of a problem and I've already had to
alter other standard services to be
bundle-aware. Which is why I think
implementing a Bundle Listener could be
a better approach for the SCI's.
I'm out of the office for a couple of
weeks so I'm going to look prototyping a
solution when I get back.
Cheers
Paul
On 29 Oct 2020, at 13:28, Grzegorz
Grzybek < [email protected]> wrote:
Hello
You're generally right. I'm working
on Pax Web 8 improvements (actual,
full implementation of OSGi CMPN R6+
Whiteboard specification +
HttpService specification + Web
Applications Specification) and I
tackled the problem of
ServletContainerInitializers.
The problem is that OSGi CMPN spec
doesn't mention SCIs at all, only
Web Applications Specification
generally assumes that "web bundle"
should be processed ("extended") by
the implementation which involves
web.xml parsing + fragments parsing
+ (possibly) "classpath scanning".
See for example:
A WAB can optionally contain a
web.xml resource to specify
additional configuration. This
web.xml must be found with the
Bundle *findEntries* method at
the path WEB-INF/web.xml. The
findEntries method includes
fragments, allowing the web.xml
to be provided by a fragment.
So here there's nothing about
"scanning other bundles" not
referred through "fragment"
relationship.
Also:
Unlike a WAR, a WAB is not
constrained to package classes
and code resources in the
WEB-INF/classes directory or
dependent JARs in WEB-INF/lib/
only. These entries can be
packaged in any way that's valid
for an OSGi bundle as long as
such directories and JARs are
part of bundle class path as set
with the Bundle-ClassPath header
and any attached fragments. JARs
that are specified in the
Bundle-ClassPath header are
treated like JARs in the
WEB-INF/lib/ directory of the
Servlet specification.
Similarly, any directory that is
part of the Bundle-ClassPath
header is treated like
WEB-INF/classes directory of the
Servlet specification.
So again - you can "bring"
additional libraries to your "bundle
classpath" by referring them in
"Bundle-ClassPath" header. No
scanning of everything (that's for
example tracked by BundleListener).
And about java.util.ServiceLoader
(which should in theory be a
suggestion to how
ServletContainerInitializer
"services" are found),
"java.util.ServiceLoader#load(java.lang.Class<S>,
java.lang.ClassLoader)" method
simply uses the passed classLoader
and the other "load()" version uses
TCCL. Neither of these methods scan
ALL classloaders (all bundles in OSGi).
In Pax Web 8 I'm definitely going to
solve this problem - for now, a
bundle that registered "a context"
(org.osgi.service.http.context.ServletContextHelper)
is an "entry point" to classLoader
"mesh" where all are checked for SCIs.
My Pax Web 8 refactoring is taking
its shape at
https://github.com/ops4j/org.ops4j.pax.web/tree/master-improvements
<https://github.com/ops4j/org.ops4j.pax.web/tree/master-improvements>
branch, but I have to do my normal
job a bit ;) So please be patient.
regards
Grzegorz Grzybek
czw., 29 paź 2020 o 14:13 'paul
stanley' via OPS4J <
[email protected]> napisał(a):
Hello.
I'm tracing this through to try
and understand why Jersey
Servlet Initializer is not
invoked for a pure Jaxrs
applications running in Karaf 4.3.0.
It appears the way that the
ServletContainerInitializerScanner
in the pax-web-api has a
fundamental design flaw when it
searches bundles for instances
of the /META-INF/services/
ServletContainerInitializerScanner
file. Namely that it only
searches dependent bundles of
the one that is being
initialised. As the
implementation of any service is
meant to be hidden by the API,
it means that you will never be
able to initialise any web
servlet. As such the
pax-jetty-web adds the bodge of
wiring-in itself to all
web-context so its
contextInitializer code can be
discovered, but no other
implementations.
Rather than performing a bundle
scan each time, surely jetty
should be implementing the
bundle listener pattern and have
the set of servlet initializers
that are available in the
platform? Or am I missing
something?
Cheers,
Paul
--
--
------------------
OPS4J - http://www.ops4j.org
<http://www.ops4j.org> -
[email protected]
---
You received this message
because you are subscribed to
the Google Groups "OPS4J" group.
To unsubscribe from this group
and stop receiving emails from
it, send an email to
[email protected].
To view this discussion on the
web visit
https://groups.google.com/d/msgid/ops4j/e9d0b4ab-33d7-4895-8a0f-e6d55e3e3b43n%40googlegroups.com
<https://groups.google.com/d/msgid/ops4j/e9d0b4ab-33d7-4895-8a0f-e6d55e3e3b43n%40googlegroups.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org
<http://www.ops4j.org> -
[email protected]
---
You received this message because
you are subscribed to the Google
Groups "OPS4J" group.
To unsubscribe from this group and
stop receiving emails from it, send
an email to
[email protected].
To view this discussion on the web
visit
https://groups.google.com/d/msgid/ops4j/CAAdXmhqcqH3h1bhJhYLb1%2B08u3dcSzFE%2BEYpe%2B62O7CbmMZHGQ%40mail.gmail.com
<https://groups.google.com/d/msgid/ops4j/CAAdXmhqcqH3h1bhJhYLb1%2B08u3dcSzFE%2BEYpe%2B62O7CbmMZHGQ%40mail.gmail.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org
<http://www.ops4j.org> - [email protected]
---
You received this message because you are
subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop
receiving emails from it, send an email to
[email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ops4j/a2363134-86ad-40e9-869b-36885ac68083n%40googlegroups.com
<https://groups.google.com/d/msgid/ops4j/a2363134-86ad-40e9-869b-36885ac68083n%40googlegroups.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org
<http://www.ops4j.org> - [email protected]
---
You received this message because you are
subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop
receiving emails from it, send an email to
[email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ops4j/CAAdXmhpRfntRwzx2oykWjf56AJtWPH2nFD59dfLBFWLO5NpCJA%40mail.gmail.com
<https://groups.google.com/d/msgid/ops4j/CAAdXmhpRfntRwzx2oykWjf56AJtWPH2nFD59dfLBFWLO5NpCJA%40mail.gmail.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org <http://www.ops4j.org>
- [email protected]
---
You received this message because you are subscribed
to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving
emails from it, send an email to
[email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ops4j/0ba73d25-16c8-4ac6-8bfd-ad9404c56664%40googlemail.com
<https://groups.google.com/d/msgid/ops4j/0ba73d25-16c8-4ac6-8bfd-ad9404c56664%40googlemail.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org <http://www.ops4j.org> -
[email protected]
---
You received this message because you are subscribed to
the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails
from it, send an email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ops4j/CAAdXmhpYfC1xBd2%3DXEGjHjut8wAb1rCc6GYmP%2B2PqTk6rLy%3DKQ%40mail.gmail.com
<https://groups.google.com/d/msgid/ops4j/CAAdXmhpYfC1xBd2%3DXEGjHjut8wAb1rCc6GYmP%2B2PqTk6rLy%3DKQ%40mail.gmail.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org <http://www.ops4j.org> -
[email protected]
---
You received this message because you are subscribed to the
Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails
from it, send an email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ops4j/38587571-05a7-4043-a381-f0a7ac6d50fb%40googlemail.com
<https://groups.google.com/d/msgid/ops4j/38587571-05a7-4043-a381-f0a7ac6d50fb%40googlemail.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org <http://www.ops4j.org> -
[email protected] <mailto:[email protected]>
---
You received this message because you are subscribed to the Google
Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected]
<mailto:[email protected]>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/ops4j/629e8714-e364-4893-8e63-5b4291abca0an%40googlegroups.com
<https://groups.google.com/d/msgid/ops4j/629e8714-e364-4893-8e63-5b4291abca0an%40googlegroups.com?utm_medium=email&utm_source=footer>.
--
--
------------------
OPS4J - http://www.ops4j.org <http://www.ops4j.org> - [email protected]
---
You received this message because you are subscribed to the Google
Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/ops4j/CAAdXmhrKq8UodOjM7ugnGeE9_FciVqATen63kZ0cPhO1bzKw%3Dg%40mail.gmail.com
<https://groups.google.com/d/msgid/ops4j/CAAdXmhrKq8UodOjM7ugnGeE9_FciVqATen63kZ0cPhO1bzKw%3Dg%40mail.gmail.com?utm_medium=email&utm_source=footer>.