Big Kudos to Grzegorz for not giving up on this in the last two years! best regards, Achim
Am Mo., 13. Sept. 2021 um 12:27 Uhr schrieb Grzegorz Grzybek < gr.grzy...@gmail.com>: > Hello! > > After almost 2 years of refactoring and development, I think Pax Web 8 is > ready for release. > Manual updates are still on my list and some exhaustive documentation (and > maybe a blog post) is being prepared... > > TL;DR: > > - `mvn clean install -DskipTests` in `main` branch of >> https://github.com/ops4j/org.ops4j.pax.web >> - start with clean Karaf 4.3.3 >> >> karaf@root()> repo-remove org.ops4j.pax.web-7.3.19 >> karaf@root()> repo-add >> mvn:org.ops4j.pax.web/pax-web-features/8.0.0-SNAPSHOT/xml/features >> karaf@root()> feature:install pax-web-http-tomcat >> karaf@root()> feature:install pax-web-war >> karaf@root()> bundle:install -s >> 'webbundle:mvn:io.hawt/hawtio-war/2.13.6/war?Web-ContextPath=/hawtio' >> >> - browse to http://localhost:8181/hawtio >> > > However I think it'd be good to describe the rationale behind the rewrite > and some key points of the new release. > > *Background information:* > > My single, initial reason to start the refactoring was > https://github.com/ops4j/org.ops4j.pax.web/issues/1413 issue (migrated > from https://ops4j1.jira.com/browse/PAXWEB-1123): "HTTP Whiteboard and > selection of the ServletContextHelper". > > Whiteboard specification says, that every web element may reference a > target ServletContextHelper using "osgi.http.whiteboard.context.select" > service registration property and its value is an LDAP filter, which may > also be: > > osgi.http.whiteboard.context.select=(osgi.http.whiteboard.context.name=*) > > which means "register the servlet into ALL available > ServletContextHelpers". > Pax Web 7 was taking the osgi.http.whiteboard.context.select property > value and was doing split("=") on it to get the name/id of the target > context... Effectively 1:1 relation was assumed, while Whiteboard > specification assumes 1:N relationship. > > So I started to rewrite the internal Pax Web model... And somehow much > much more was refactored. > > *Pax Web 8 goals:* > > - I've carefully read chapters 102 (Http Service specification), 128 > (Web Applications specification) and 140 (Whiteboard specification) of OSGi > CMPN R7 and tried to implement everything in best possible way > - I always appreciated how well and cleverly Pax Web was written by > others from this list: > > 11:41 $ git shortlog -snc origin/pax-web-7.2.x >> 894 adreghi...@gmail.com >> 747 anierbeck >> 284 Achim Nierbeck >> 182 ANierbeck >> 123 Guillaume Nodet >> 114 Jean-Baptiste Onofré >> 103 Marc Schlegel >> 77 jbonofre >> 53 lostiniceland >> 44 Stephan Siano >> 37 Harald Wellmann >> 21 Marc Klinger >> 20 Freeman Fang >> ... >> > > - I wanted to keep the "spirit" of Pax Web - emphasizing target > runtime (Jetty, Tomcat, Undertow) over "specification first" approach > - I wanted to ensure that everything in Pax Web works as similar as > possible in all 3 supported runtimes > - I wanted to keep the possibility to use native container > configuration (jetty.xml, tomcat-server.xml, undertow.xml) in addition to > what we can pass through org.ops4j.pax.web PID > - I wanted to make Pax Web 8 more reliable (no more flaky tests, no > more random Thread.sleep() in tests, ...) > > *Pax Web 8 highlights:* > > - Latest versions of Jetty 9.4.x, Tomcat 9.0.x (without TIPI!) and > Undertow 2.2.x are used > - Web "elements" mentioned in Http Service and Whiteboard > specifications are handled: servlets, filters, listeners, error pages > - additionally, Pax Web 8 supports everything that can be configured > in web.xml besides: <env-entry>, <post-construct>, <pre-destroy>, > <resource-env-ref>, <resource-ref>, <administered-object>, > <connection-factory>, <data-source>, <default-context-path>, <description>, > <ejb-local-ref>, <ejb-ref>, <icon>, <jms-connection-factory>, > <jms-destination>, <mail-session>, <message-destination>, > <message-destination-ref>, <module-name>, <persistence-context-ref>, > <persistence-unit-ref>, <service-ref> > - "above" what we can find in web.xml, Pax Web 8 supports: > - ServletContainerInitializers (SCI) - proved by working > JSF/Primefaces/Vaadin examples > - web-fragment.xmls > - annotated web elements (@WebServlet, @WebFilter, @WebListener) > - META-INF/resources locations > - websockets via HttpService and Whiteboard > - web fragment scanning using tomcat-util-scanner > - without any mention in any CMPN specification, JSPs, welcome-pages, > security configurations are supported > - no more xbean used to scan the "class space" > - no more dependency to ASM > - single configuration thread that operates on global model and > synchronizes the model changes with the state of target runtime (Jetty, > Tomcat, Undertow) > - consistent structure of pax-web-jetty, pax-web-tomcat and > pax-web-undertow: > - there's single > org.ops4j.pax.web.service.<runtime>.internal.<Runtime>ServerController > class (per runtime) implementing > org.ops4j.pax.web.service.spi.ServerController#sendBatch() method > - org.ops4j.pax.web.service.spi.task.Batch is a sequence of > "operations" that change the model or affect the runtime > - there's single > org.ops4j.pax.web.service.<runtime>.internal.<Runtime>ServerWrapper > class > (per runtime) that: > - keeps an instance of the "server" > (org.eclipse.jetty.server.Server, > org.apache.catalina.core.StandardServer > or io.undertow.server.HttpHandler + collection of > org.xnio.channels.AcceptingChannels) - Pax Web 8 DOESN'T use > easy-to-use > io.undertow.Undertow class! > - implements org.ops4j.pax.web.service.spi.task.BatchVisitor > interface that's used to react to state-changing operations (like > registration of a servlet) - mind that a "batch" may be > "transactional" > - each runtime bundle contains some overriden runtime classes (like > org.ops4j.pax.web.service.jetty.internal.PaxWebFilterHolder that extends > org.eclipse.jetty.servlet.FilterHolder) > - Knowing that we have 3 "ways into" the Pax Web (HttpService, > Whiteboard, WABs), Pax Web 8 introduces the concept of "the view of the > WebContainer" - each "way" uses specific "view" to interact with Pax Web > runtime > - The model is greatly simplified comparing to Pax Web 7: > - there exist "model" classes (like > org.ops4j.pax.web.service.spi.model.elements.ServletModel) which are > held > internall and passed around between whiteboard, war, runtime and target > container bundles > - from Whiteboard perspective, the "incoming" services, like > "javax.servlet.Servlet" or > "org.osgi.service.http.context.ServletContextHelper" are "tracked into" > the > model classes, so whether the servlet is registered by HttpService, > Whiteboard or through a WAB, its processing is consistent and there's no > problem mixing WABs, Whiteboard and HttpService approaches > - the "model" classes are divided into "web elements" and "web > contexts" and each "web element" may reference one or many "web > contexts" > and the relation is dynamic > - ... > > *Pax Web 8 example:* > > The most important use-case is: > > - user/bundle registers (Whiteboard approach) a servlet without > specifying a "context" and the servlet has mapping "/my-servlet" > - this servlet should be available at URL > http://localhost:8181/my-servlet > - another user/bundle registers a > org.osgi.service.http.context.ServletContextHelper service with > "osgi.http.whiteboard.context.path=/my-context" and " > osgi.http.whiteboard.context.name=default" properties > - *immediately* (asap) the first servlet should be available at > http://localhost:8181/my-context/my-servlet and *no longer* it should > be available at the first URL > > Yes, it works. Also shadowing may happen, because when two servlets are > registered with the same name and target context, only the one with higher > ranking/lower service.id should be available. There are many integration > tests that show what happens when conflicting services are registered > across different contexts. > > *Summary*: > > If you have some time, please checkout > https://github.com/ops4j/org.ops4j.pax.web/tree/main, `mvn clean > -DskipTests` it and give it a try. > > For example in Karaf 4.3.3 (after uncommenting "karaf" user in > `etc/users.properties`) we can do: > > karaf@root()> repo-remove org.ops4j.pax.web-7.3.19 >> Removing features repository: >> mvn:org.ops4j.pax.web/pax-web-features/7.3.19/xml/features >> karaf@root()> repo-add >> mvn:org.ops4j.pax.web/pax-web-features/8.0.0-SNAPSHOT/xml/features >> Adding feature url >> mvn:org.ops4j.pax.web/pax-web-features/8.0.0-SNAPSHOT/xml/features >> karaf@root()> feature:install pax-web-http-tomcat >> karaf@root()> feature:install pax-web-war >> karaf@root()> bundle:install >> 'webbundle:mvn:io.hawt/hawtio-war/2.13.6/war?Web-ContextPath=/hawtio' >> Bundle ID: 68 >> karaf@root()> start 68 >> > > Then you can log in to http://localhost:8181/hawtio using karaf/karaf > credentials (JAAS based authentication) and then navigate to > http://localhost:8181/hawtio/jmx/attributes?nid=root-Catalina-WebResourceRoot-localhost-%2FServletContextModel-3-Cache > which shows cache configuration for the default (resource) servlet used by > /hawtio WAB. > > kind regards and thanks for the patience ;) > Grzegorz Grzybek > > -- > -- > ------------------ > OPS4J - http://www.ops4j.org - op...@googlegroups.com > > --- > 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 ops4j+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/ops4j/CAAdXmhpRUK%2B-0fSYnXMXUevpfuDDLgSqhLXdq83Tae3c6usnCQ%40mail.gmail.com > <https://groups.google.com/d/msgid/ops4j/CAAdXmhpRUK%2B-0fSYnXMXUevpfuDDLgSqhLXdq83Tae3c6usnCQ%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > -- Apache Member Apache Karaf <http://karaf.apache.org/> Committer & PMC OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer & Project Lead blog <http://notizblog.nierbeck.de/> Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>