From 1abaeb6cee6195cd2926d295309dbd00adcfbe11 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 22 Dec 2022 01:12:44 +1100 Subject: [PATCH] Jetty 12.0.x osgi (#9068) --- .../org/eclipse/jetty/http/MimeTypes.java | 1 + jetty-core/jetty-osgi/pom.xml | 158 +++++ .../jetty/osgi/AbstractContextProvider.java | 286 ++++++++ .../jetty/osgi}/BundleContextProvider.java | 83 ++- .../eclipse/jetty/osgi}/BundleProvider.java | 2 +- .../jetty/osgi}/BundleWebAppProvider.java | 111 ++-- .../eclipse/jetty/osgi/ContextFactory.java | 16 +- .../jetty/osgi/JettyBootstrapActivator.java | 153 +++-- .../jetty/osgi/JettyServerFactory.java | 261 ++++++++ .../jetty/osgi}/LibExtClassLoaderHelper.java | 5 +- .../java/org/eclipse/jetty/osgi/OSGiApp.java | 259 ++++++++ .../org/eclipse/jetty/osgi}/OSGiDeployer.java | 23 +- .../jetty/osgi}/OSGiServerConstants.java | 15 +- .../eclipse/jetty/osgi}/OSGiUndeployer.java | 19 +- .../jetty/osgi}/OSGiWebappConstants.java | 9 +- .../osgi/util}/BundleClassLoaderHelper.java | 5 +- .../util}/BundleClassLoaderHelperFactory.java | 2 +- .../osgi/util}/BundleFileLocatorHelper.java | 5 +- .../util}/BundleFileLocatorHelperFactory.java | 2 +- .../util}/DefaultBundleClassLoaderHelper.java | 3 +- .../osgi/util}/DefaultFileLocatorHelper.java | 13 +- .../eclipse/jetty/osgi/util}/EventSender.java | 2 +- .../jetty/osgi/util}/FakeURLClassLoader.java | 2 +- .../jetty/osgi/util}/OSGiClassLoader.java | 2 +- .../osgi/util/ServerClasspathContributor.java | 21 +- .../osgi/util}/ServerConnectorListener.java | 2 +- .../org/eclipse/jetty/osgi/util}/Util.java | 117 +++- jetty-core/pom.xml | 6 +- .../ee10/annotations/AnnotationParser.java | 12 +- jetty-ee10/jetty-ee10-apache-jsp/pom.xml | 2 +- .../jetty-ee10-demo-jetty-webapp/pom.xml | 3 +- .../jetty-ee10-demo-jsp-webapp/pom.xml | 3 +- .../jetty-ee10-demo-spec-webapp/pom.xml | 5 +- .../templates/annotations-context-header.xml | 4 +- .../src/main/templates/env-definitions.xml | 4 +- .../jetty-ee10-osgi-boot-jsp/pom.xml | 14 +- .../jasper/ContainerTldBundleDiscoverer.java | 249 ------- .../boot/jasper/JSTLBundleDiscoverer.java | 178 ----- .../ee10/osgi/boot/jsp/FragmentActivator.java | 30 +- .../jsp/TLDServerClasspathContributor.java | 112 ++++ .../jettyhome/etc/jetty-deploy.xml | 6 - .../jettyhome/etc/jetty.xml | 40 +- .../jetty-ee10-osgi-boot/pom.xml | 36 +- .../annotations/AnnotationConfiguration.java | 20 +- .../osgi/annotations/AnnotationParser.java | 198 ++---- .../osgi/boot/AbstractContextProvider.java | 235 ------- .../jetty/ee10/osgi/boot/AbstractOSGiApp.java | 195 ------ .../osgi/boot/AbstractWebAppProvider.java | 553 ---------------- .../ee10/osgi/boot/BundleWebAppProvider.java | 257 -------- .../jetty/ee10/osgi/boot/EE10Activator.java | 613 ++++++++++++++++++ .../osgi/boot/JettyBootstrapActivator.java | 126 ---- .../jetty/ee10/osgi/boot/OSGiDeployer.java | 77 --- .../osgi/boot/OSGiMetaInfConfiguration.java | 59 +- .../ee10/osgi/boot/OSGiServerConstants.java | 83 --- .../jetty/ee10/osgi/boot/OSGiUndeployer.java | 54 -- .../osgi/boot/OSGiWebInfConfiguration.java | 31 - .../webapp => }/OSGiWebappClassLoader.java | 122 +--- .../ee10/osgi/boot/OSGiWebappConstants.java | 138 ---- .../PackageAdminServiceTracker.java | 47 +- .../osgi/boot/ServiceContextProvider.java | 224 ------- .../jetty/ee10/osgi/boot/ServiceProvider.java | 29 - .../ee10/osgi/boot/ServiceWebAppProvider.java | 256 -------- .../JettyServerServiceTracker.java | 92 --- .../serverfactory/ServerInstanceWrapper.java | 441 ------------- .../webapp/LibExtClassLoaderHelper.java | 196 ------ .../boot/utils/BundleClassLoaderHelper.java | 53 -- .../utils/BundleClassLoaderHelperFactory.java | 56 -- .../boot/utils/BundleFileLocatorHelper.java | 118 ---- .../utils/BundleFileLocatorHelperFactory.java | 54 -- .../ee10/osgi/boot/utils/EventSender.java | 84 --- .../osgi/boot/utils/FakeURLClassLoader.java | 66 -- .../ee10/osgi/boot/utils/OSGiClassLoader.java | 160 ----- .../boot/utils/ServerConnectorListener.java | 91 --- .../osgi/boot/utils/TldBundleDiscoverer.java | 36 - .../jetty/ee10/osgi/boot/utils/Util.java | 166 ----- .../DefaultBundleClassLoaderHelper.java | 428 ------------ .../internal/DefaultFileLocatorHelper.java | 385 ----------- ...rg.eclipse.jetty.ee10.webapp.Configuration | 2 +- jetty-ee10/jetty-ee10-osgi/pom.xml | 64 +- .../test-jetty-ee10-osgi-context/pom.xml | 79 --- .../src/main/context/acme.xml | 23 - .../main/java/com/acme/osgi/Activator.java | 72 -- .../src/main/resources/static/index.html | 6 - .../test-jetty-ee10-osgi-server/pom.xml | 2 +- .../pom.xml | 3 +- .../test-jetty-ee10-osgi-webapp/pom.xml | 61 -- .../main/java/com/acme/osgi/Activator.java | 91 --- .../src/main/resources/index.html | 6 - .../src/main/resources/webappA/index.html | 6 - .../src/main/resources/webappB/index.html | 6 - .../test-jetty-ee10-osgi/pom.xml | 94 ++- .../src/test/config/etc/jetty-deploy.xml | 4 - .../jetty-http-boot-context-as-service.xml | 48 -- .../etc/jetty-http-boot-webapp-as-service.xml | 48 -- .../etc/jetty-http-boot-with-annotations.xml | 2 +- .../etc/jetty-http-boot-with-bundle.xml | 2 +- ...jetty-http-boot-with-jakarta-websocket.xml | 2 +- .../config/etc/jetty-http-boot-with-jsp.xml | 2 +- .../etc/jetty-http-boot-with-resources.xml | 2 +- .../etc/jetty-http-boot-with-websocket.xml | 2 +- .../src/test/config/etc/jetty-http2.xml | 16 +- .../src/test/config/etc/jetty-https.xml | 8 +- .../src/test/config/etc/jetty-ssl-context.xml | 60 ++ .../src/test/config/etc/jetty-ssl.xml | 57 +- .../src/test/config/etc/jetty-testrealm.xml | 23 +- .../src/test/config/etc/jetty.xml | 26 - .../test/TestJettyOSGiAnnotationParser.java | 10 +- .../TestJettyOSGiBootContextAsService.java | 116 ---- .../test/TestJettyOSGiBootHTTP2Conscrypt.java | 13 +- .../osgi/test/TestJettyOSGiBootHTTP2JDK9.java | 12 +- .../TestJettyOSGiBootWebAppAsService.java | 142 ---- .../TestJettyOSGiBootWithAnnotations.java | 24 +- .../test/TestJettyOSGiBootWithBundle.java | 119 ---- ...TestJettyOSGiBootWithJakartaWebSocket.java | 18 +- .../osgi/test/TestJettyOSGiBootWithJsp.java | 9 +- .../test/TestJettyOSGiBootWithWebSocket.java | 8 +- .../test/TestJettyOSGiClasspathResources.java | 10 +- .../jetty/ee10/osgi/test/TestOSGiUtil.java | 79 ++- .../test/resources/jetty-logging.properties | 1 + .../pom.xml | 2 +- .../pom.xml | 4 +- .../pom.xml | 2 +- jetty-ee10/pom.xml | 3 +- .../ee9/annotations/AnnotationParser.java | 10 +- .../jetty-ee9-demo-jetty-webapp/pom.xml | 3 +- .../jetty-ee9-demo-jsp-webapp/pom.xml | 1 + .../jetty-ee9-demo-spec-webapp/pom.xml | 3 +- .../jetty-ee9-osgi-alpn/pom.xml | 33 - .../jasper/ContainerTldBundleDiscoverer.java | 249 ------- .../boot/jasper/JSTLBundleDiscoverer.java | 178 ----- .../ee9/osgi/boot/jsp/FragmentActivator.java | 30 +- .../jsp/TLDServerClasspathContributor.java | 112 ++++ .../jetty-ee9-osgi-boot-warurl/pom.xml | 42 -- .../ee9/osgi/boot/warurl/WarUrlActivator.java | 69 -- .../osgi/boot/warurl/WarUrlStreamHandler.java | 98 --- .../internal/WarBundleManifestGenerator.java | 276 -------- .../warurl/internal/WarURLConnection.java | 360 ---------- .../jettyhome/etc/jetty-deploy.xml | 6 - .../jettyhome/etc/jetty.xml | 42 +- .../jetty-ee9-osgi-boot/pom.xml | 13 +- .../annotations/AnnotationConfiguration.java | 14 +- .../osgi/annotations/AnnotationParser.java | 184 ++---- .../osgi/boot/AbstractContextProvider.java | 230 ------- .../jetty/ee9/osgi/boot/AbstractOSGiApp.java | 195 ------ .../ee9/osgi/boot/AbstractWebAppProvider.java | 553 ---------------- .../ee9/osgi/boot/BundleContextProvider.java | 199 ------ .../jetty/ee9/osgi/boot/EE9Activator.java | 611 +++++++++++++++++ .../osgi/boot/JettyBootstrapActivator.java | 126 ---- .../osgi/boot/OSGiMetaInfConfiguration.java | 58 +- .../osgi/boot/OSGiWebInfConfiguration.java | 31 - .../webapp => }/OSGiWebappClassLoader.java | 122 +--- .../PackageAdminServiceTracker.java | 2 +- .../ee9/osgi/boot/ServiceContextProvider.java | 224 ------- .../ee9/osgi/boot/ServiceWebAppProvider.java | 256 -------- .../DefaultJettyAtJettyHomeHelper.java | 334 ---------- .../JettyServerServiceTracker.java | 92 --- .../serverfactory/ServerInstanceWrapper.java | 441 ------------- .../osgi/boot/utils/TldBundleDiscoverer.java | 36 - ...org.eclipse.jetty.ee9.webapp.Configuration | 2 +- .../contexts/httpservice.xml | 18 - .../jetty-ee9-osgi-httpservice/pom.xml | 81 --- .../HttpServiceErrorHandlerHelper.java | 39 -- .../HttpServiceErrorPageErrorHandler.java | 72 -- jetty-ee9/jetty-ee9-osgi/pom.xml | 11 +- .../test-jetty-ee9-osgi-context/pom.xml | 75 --- .../src/main/context/acme.xml | 22 - .../main/java/com/acme/osgi/Activator.java | 72 -- .../src/main/resources/static/index.html | 6 - .../test-jetty-ee9-osgi-server/pom.xml | 4 + .../pom.xml | 1 + .../test-jetty-ee9-osgi-webapp/pom.xml | 61 -- .../main/java/com/acme/osgi/Activator.java | 91 --- .../src/main/resources/index.html | 6 - .../src/main/resources/webappA/index.html | 6 - .../src/main/resources/webappB/index.html | 6 - .../test-jetty-ee9-osgi/pom.xml | 61 +- .../src/test/config/etc/jetty-deploy.xml | 4 +- .../jetty-http-boot-context-as-service.xml | 2 +- .../etc/jetty-http-boot-webapp-as-service.xml | 2 +- .../etc/jetty-http-boot-with-annotations.xml | 2 +- .../etc/jetty-http-boot-with-bundle.xml | 2 +- ...jetty-http-boot-with-jakarta-websocket.xml | 2 +- .../config/etc/jetty-http-boot-with-jsp.xml | 2 +- .../etc/jetty-http-boot-with-resources.xml | 2 +- .../etc/jetty-http-boot-with-websocket.xml | 2 +- .../src/test/config/etc/jetty-testrealm.xml | 23 +- .../src/test/config/etc/jetty.xml | 26 - .../test/TestJettyOSGiAnnotationParser.java | 5 +- .../TestJettyOSGiBootContextAsService.java | 114 ---- .../test/TestJettyOSGiBootHTTP2Conscrypt.java | 3 +- .../osgi/test/TestJettyOSGiBootHTTP2JDK9.java | 3 +- .../TestJettyOSGiBootWebAppAsService.java | 140 ---- .../TestJettyOSGiBootWithAnnotations.java | 12 +- .../test/TestJettyOSGiBootWithBundle.java | 117 ---- ...TestJettyOSGiBootWithJakartaWebSocket.java | 12 +- .../osgi/test/TestJettyOSGiBootWithJsp.java | 4 +- .../test/TestJettyOSGiBootWithWebSocket.java | 9 +- .../test/TestJettyOSGiClasspathResources.java | 2 +- .../jetty/ee9/osgi/test/TestOSGiUtil.java | 37 +- jetty-ee9/pom.xml | 2 +- pom.xml | 5 + 201 files changed, 3577 insertions(+), 12237 deletions(-) create mode 100644 jetty-core/jetty-osgi/pom.xml create mode 100644 jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/AbstractContextProvider.java rename {jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/BundleContextProvider.java (69%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/BundleProvider.java (95%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/BundleWebAppProvider.java (70%) rename jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceProvider.java => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/ContextFactory.java (58%) rename jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyBootstrapActivator.java (73%) create mode 100644 jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyServerFactory.java rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/webapp => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/LibExtClassLoaderHelper.java (99%) create mode 100644 jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiApp.java rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/OSGiDeployer.java (74%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/OSGiServerConstants.java (86%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/OSGiUndeployer.java (71%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi}/OSGiWebappConstants.java (94%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/BundleClassLoaderHelper.java (87%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/BundleClassLoaderHelperFactory.java (97%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/BundleFileLocatorHelper.java (94%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/BundleFileLocatorHelperFactory.java (97%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/DefaultBundleClassLoaderHelper.java (99%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/DefaultFileLocatorHelper.java (95%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/EventSender.java (98%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/FakeURLClassLoader.java (97%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/OSGiClassLoader.java (98%) rename jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleProvider.java => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerClasspathContributor.java (62%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/ServerConnectorListener.java (98%) rename {jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils => jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util}/Util.java (59%) delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/ContainerTldBundleDiscoverer.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/JSTLBundleDiscoverer.java create mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/TLDServerClasspathContributor.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractContextProvider.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractOSGiApp.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractWebAppProvider.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleWebAppProvider.java create mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/EE10Activator.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/JettyBootstrapActivator.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiDeployer.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiServerConstants.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiUndeployer.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebInfConfiguration.java rename jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/{internal/webapp => }/OSGiWebappClassLoader.java (54%) delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappConstants.java rename jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/{utils/internal => }/PackageAdminServiceTracker.java (92%) delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceContextProvider.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceProvider.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceWebAppProvider.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelper.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelperFactory.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelper.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelperFactory.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/EventSender.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/FakeURLClassLoader.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/OSGiClassLoader.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/ServerConnectorListener.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/TldBundleDiscoverer.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/Util.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultFileLocatorHelper.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/pom.xml delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/context/acme.xml delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/java/com/acme/osgi/Activator.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/resources/static/index.html delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/pom.xml delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/java/com/acme/osgi/Activator.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/index.html delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappA/index.html delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappB/index.html delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml create mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl-context.xml delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootContextAsService.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootWebAppAsService.java delete mode 100644 jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootWithBundle.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-alpn/pom.xml delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee9/osgi/boot/jasper/ContainerTldBundleDiscoverer.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee9/osgi/boot/jasper/JSTLBundleDiscoverer.java create mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee9/osgi/boot/jsp/TLDServerClasspathContributor.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-warurl/pom.xml delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee9/osgi/boot/warurl/WarUrlActivator.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee9/osgi/boot/warurl/WarUrlStreamHandler.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee9/osgi/boot/warurl/internal/WarBundleManifestGenerator.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee9/osgi/boot/warurl/internal/WarURLConnection.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractContextProvider.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractOSGiApp.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractWebAppProvider.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleContextProvider.java create mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/EE9Activator.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/JettyBootstrapActivator.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebInfConfiguration.java rename jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/{internal/webapp => }/OSGiWebappClassLoader.java (54%) rename jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/{utils/internal => }/PackageAdminServiceTracker.java (99%) delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceContextProvider.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceWebAppProvider.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/TldBundleDiscoverer.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/contexts/httpservice.xml delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/pom.xml delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorHandlerHelper.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorPageErrorHandler.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/pom.xml delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/context/acme.xml delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/java/com/acme/osgi/Activator.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/resources/static/index.html delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/pom.xml delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/java/com/acme/osgi/Activator.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/index.html delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappA/index.html delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappB/index.html delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootContextAsService.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootWebAppAsService.java delete mode 100644 jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootWithBundle.java diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java index c0e4008e524..3de720c4865 100644 --- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java +++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java @@ -192,6 +192,7 @@ public class MimeTypes .withAll(() -> { Map result = new HashMap<>(); + for (Type type : Type.values()) { String key1 = type.toString(); diff --git a/jetty-core/jetty-osgi/pom.xml b/jetty-core/jetty-osgi/pom.xml new file mode 100644 index 00000000000..0cf1afb1728 --- /dev/null +++ b/jetty-core/jetty-osgi/pom.xml @@ -0,0 +1,158 @@ + + + org.eclipse.jetty + jetty-core + 12.0.0-SNAPSHOT + + + 4.0.0 + jetty-osgi + Jetty Core :: OSGi + Support for OSGi integration + + + ${project.groupId}.osgi + org.eclipse.jetty.osgi.* + 3.18.100 + 3.11.0 + 1.6.1 + 1.5.0 + 1.4.1 + 3.7.100 + 1.2.0 + 1.2.0 + 1.0.2 + 1.0.1 + 1.5.4 + 1.0.2 + 1.0.0-v20070606 + true + + + + + + maven-surefire-plugin + + + @{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.server=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.server/org.eclipse.jetty.server=ALL-UNNAMED + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.eclipse.jetty.osgi.JettyBootstrapActivator + org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))" + <_nouses>true + + + + + + + + + org.eclipse.platform + org.eclipse.osgi.services + ${osgi-services-version} + + + + jakarta.servlet + servlet-api + + + + org.apache.felix + org.osgi.foundation + + + + + + org.eclipse.platform + org.eclipse.osgi + ${osgi-version} + + + org.osgi + org.osgi.service.cm + ${osgi-service-cm-version} + + + org.osgi + org.osgi.service.component + ${osgi-service-component-version} + + + org.osgi + org.osgi.service.event + ${osgi-service-event-version} + + + org.osgi + org.osgi.util.tracker + ${osgi-util-tracker-version} + + + org.eclipse.equinox.http + servlet + ${equinox-http-servlet-version} + + + + + + + org.eclipse.jetty + jetty-server + + + org.eclipse.jetty + jetty-ee + + + org.eclipse.jetty + jetty-deploy + + + org.eclipse.platform + org.eclipse.osgi + + + org.eclipse.platform + org.eclipse.osgi.services + + + org.osgi + org.osgi.service.cm + + + org.osgi + org.osgi.service.event + + + org.osgi + org.osgi.util.tracker + + + + org.slf4j + slf4j-api + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + diff --git a/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/AbstractContextProvider.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/AbstractContextProvider.java new file mode 100644 index 00000000000..3ef010e99d5 --- /dev/null +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/AbstractContextProvider.java @@ -0,0 +1,286 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.osgi; + +import java.io.File; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.jetty.deploy.App; +import org.eclipse.jetty.deploy.AppProvider; +import org.eclipse.jetty.deploy.DeploymentManager; +import org.eclipse.jetty.ee.Deployable; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.OSGiClassLoader; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.component.Environment; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.xml.XmlConfiguration; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * AbstractContextProvider + * + * Base class for DeploymentManager Providers that can deploy ContextHandlers into + * Jetty that have been discovered via OSGI either as bundles or services. + */ +public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider +{ + private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); + + private DeploymentManager _deploymentManager; + private Server _server; + private ContextFactory _contextFactory; + private String _environment; + private final Map _properties = new HashMap<>(); + + public AbstractContextProvider(String environment, Server server, ContextFactory contextFactory) + { + _environment = Objects.requireNonNull(environment); + _server = Objects.requireNonNull(server); + _contextFactory = Objects.requireNonNull(contextFactory); + } + + public Server getServer() + { + return _server; + } + + public Map getProperties() + { + return _properties; + } + + @Override + public ContextHandler createContextHandler(App app) throws Exception + { + if (app == null) + return null; + + //Create a ContextHandler suitable to deploy in OSGi + ContextHandler h = _contextFactory.createContextHandler(this, app); + + return h; + } + + @Override + public void setDeploymentManager(DeploymentManager deploymentManager) + { + _deploymentManager = deploymentManager; + } + + @Override + public String getEnvironmentName() + { + return _environment; + } + + public DeploymentManager getDeploymentManager() + { + return _deploymentManager; + } + + /** + * Get the extractWars. + * This is equivalent to getting the {@link Deployable#EXTRACT_WARS} property. + * + * @return the extractWars + */ + public boolean isExtractWars() + { + return Boolean.parseBoolean(_properties.get(Deployable.EXTRACT_WARS)); + } + + /** + * Set the extractWars. + * This is equivalent to setting the {@link Deployable#EXTRACT_WARS} property. + * + * @param extractWars the extractWars to set + */ + public void setExtractWars(boolean extractWars) + { + _properties.put(Deployable.EXTRACT_WARS, Boolean.toString(extractWars)); + } + + /** + * Get the parentLoaderPriority. + * This is equivalent to getting the {@link Deployable#PARENT_LOADER_PRIORITY} property. + * + * @return the parentLoaderPriority + */ + public boolean isParentLoaderPriority() + { + return Boolean.parseBoolean(_properties.get(Deployable.PARENT_LOADER_PRIORITY)); + } + + /** + * Set the parentLoaderPriority. + * This is equivalent to setting the {@link Deployable#PARENT_LOADER_PRIORITY} property. + * + * @param parentLoaderPriority the parentLoaderPriority to set + */ + public void setParentLoaderPriority(boolean parentLoaderPriority) + { + _properties.put(Deployable.PARENT_LOADER_PRIORITY, Boolean.toString(parentLoaderPriority)); + } + + /** + * Get the defaultsDescriptor. + * This is equivalent to getting the {@link Deployable#DEFAULTS_DESCRIPTOR} property. + * + * @return the defaultsDescriptor + */ + public String getDefaultsDescriptor() + { + return _properties.get(Deployable.DEFAULTS_DESCRIPTOR); + } + + /** + * Set the defaultsDescriptor. + * This is equivalent to setting the {@link Deployable#DEFAULTS_DESCRIPTOR} property. + * + * @param defaultsDescriptor the defaultsDescriptor to set + */ + public void setDefaultsDescriptor(String defaultsDescriptor) + { + _properties.put(Deployable.DEFAULTS_DESCRIPTOR, defaultsDescriptor); + } + + /** + * This is equivalent to setting the {@link Deployable#CONFIGURATION_CLASSES} property. + * @param configurations The configuration class names as a comma separated list + */ + public void setConfigurationClasses(String configurations) + { + setConfigurationClasses(StringUtil.isBlank(configurations) ? null : configurations.split(",")); + } + + /** + * This is equivalent to setting the {@link Deployable#CONFIGURATION_CLASSES} property. + * @param configurations The configuration class names. + */ + public void setConfigurationClasses(String[] configurations) + { + _properties.put(Deployable.CONFIGURATION_CLASSES, (configurations == null) + ? null + : String.join(",", configurations)); + } + + /** + * + * This is equivalent to getting the {@link Deployable#CONFIGURATION_CLASSES} property. + * @return The configuration class names. + */ + public String[] getConfigurationClasses() + { + String cc = _properties.get(Deployable.CONFIGURATION_CLASSES); + return cc == null ? new String[0] : cc.split(","); + } + + /** + * Set the temporary directory for deployment. + *

+ * This is equivalent to setting the {@link Deployable#BASE_TEMP_DIR} property. + * If not set, then the java.io.tmpdir System Property is used. + * + * @param directory the new work directory + */ + public void setTempDir(String directory) + { + _properties.put(Deployable.BASE_TEMP_DIR, directory); + } + + /** + * Set the temporary directory for deployment. + *

+ * This is equivalent to setting the {@link Deployable#BASE_TEMP_DIR} property. + * If not set, then the java.io.tmpdir System Property is used. + * + * @param directory the new work directory + */ + public void setTempDir(File directory) + { + _properties.put(Deployable.BASE_TEMP_DIR, directory.getAbsolutePath()); + } + + /** + * Get the temporary directory for deployment. + *

+ * This is equivalent to getting the {@link Deployable#BASE_TEMP_DIR} property. + * + * @return the user supplied work directory (null if user has not set Temp Directory yet) + */ + public File getTempDir() + { + String tmpDir = _properties.get(Deployable.BASE_TEMP_DIR); + return tmpDir == null ? null : new File(tmpDir); + } + + /** + * @param tldBundles Comma separated list of bundles that contain tld jars + * that should be setup on the context instances created here. + */ + public void setTldBundles(String tldBundles) + { + _properties.put(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, tldBundles); + } + + /** + * @return The list of bundles that contain tld jars that should be setup on + * the contexts create here. + */ + public String getTldBundles() + { + return _properties.get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); + } + + public boolean isDeployable(Bundle bundle) + { + if (bundle == null) + return false; + + //check environment matches + if (getEnvironmentName().equalsIgnoreCase(bundle.getHeaders().get(OSGiWebappConstants.JETTY_ENVIRONMENT))) + return true; + + return false; + } + + public boolean isDeployable(ServiceReference service) + { + if (service == null) + return false; + + //has it been deployed before? + if (!StringUtil.isBlank((String)service.getProperty(OSGiWebappConstants.WATERMARK))) + return false; + + //destined for our environment? + if (getEnvironmentName().equalsIgnoreCase((String)service.getProperty(OSGiWebappConstants.JETTY_ENVIRONMENT))) + return true; + + return false; + } +} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleContextProvider.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleContextProvider.java similarity index 69% rename from jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleContextProvider.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleContextProvider.java index b1102ad2528..0a43fd33ef9 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleContextProvider.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleContextProvider.java @@ -11,8 +11,11 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.osgi.boot; +package org.eclipse.jetty.osgi; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Dictionary; import java.util.HashMap; @@ -21,7 +24,8 @@ import java.util.List; import java.util.Map; import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; +import org.eclipse.jetty.osgi.util.Util; +import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.StringUtil; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -41,22 +45,31 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu { private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); - private Map _appMap = new HashMap(); + private Map _appMap = new HashMap<>(); - private Map> _bundleMap = new HashMap>(); + private Map> _bundleMap = new HashMap<>(); private ServiceRegistration _serviceRegForBundles; private BundleTracker _tracker; + /** + * ContextBundleTracker + * + * Track deployment of Bundles that should be deployed to Jetty as contexts. + */ public class ContextBundleTracker extends BundleTracker { - protected String _managedServerName; + protected String _serverName; - public ContextBundleTracker(BundleContext bundleContext, String managedServerName) + /** + * @param bundleContext our bundle + * @param serverName the Server instance to which we will deploy contexts + */ + public ContextBundleTracker(BundleContext bundleContext, String serverName) { super(bundleContext, Bundle.ACTIVE | Bundle.STOPPING, null); - _managedServerName = managedServerName; + _serverName = serverName; } @Override @@ -65,8 +78,8 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu try { String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME)) || - (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName)))) + if ((StringUtil.isBlank(serverName) && _serverName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME)) || + (!StringUtil.isBlank(serverName) && (serverName.equals(_serverName)))) { if (bundleAdded(bundle)) return bundle; @@ -93,21 +106,23 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu } } - public BundleContextProvider(ServerInstanceWrapper wrapper) + public BundleContextProvider(String environment, Server server, ContextFactory contextFactory) { - super(wrapper); + super(environment, server, contextFactory); } @Override protected void doStart() throws Exception { + String serverName = (String)getServer().getAttribute(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + //Track bundles that are ContextHandlers that should be deployed - _tracker = new ContextBundleTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName()); + _tracker = new ContextBundleTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), serverName); _tracker.open(); //register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to Dictionary properties = new Hashtable(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); + properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName); _serviceRegForBundles = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(BundleProvider.class.getName(), this, properties); super.doStart(); } @@ -131,35 +146,49 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu } } + /** + * Deploy a bundle as a Jetty context. + */ @Override public boolean bundleAdded(Bundle bundle) throws Exception { if (bundle == null) return false; + + if (!isDeployable(bundle)) + return false; //If the bundle defines a Web-ContextPath then its probably a webapp and the BundleWebAppProvider should deploy it - if ((String)bundle.getHeaders().get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) != null) + if (bundle.getHeaders().get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) != null) { if (LOG.isDebugEnabled()) LOG.debug("BundleContextProvider ignoring bundle {} with {} set", bundle.getSymbolicName(), OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); return false; } + + //comma separated list of context xml files, each of which is a separate ContextHandler to deploy + String contextFiles = bundle.getHeaders().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); - String contextFiles = (String)bundle.getHeaders().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); - + //no contexts to deploy, ignore it if (contextFiles == null) return false; + //is the bundle destined for my environment? + String jettyHome = (String)getServer().getAttribute(OSGiServerConstants.JETTY_HOME); + Path jettyHomePath = (StringUtil.isBlank(jettyHome) ? null : Paths.get(jettyHome)); + boolean added = false; - //bundle defines JETTY_CONTEXT_FILE_PATH header, - //a comma separated list of context xml files that each define a ContextHandler - //TODO: (could be WebAppContexts) + String[] tmp = contextFiles.split("[,;]"); for (String contextFile : tmp) - { - String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-" + contextFile; - OSGiApp app = new OSGiApp(getDeploymentManager(), this, originId, bundle, contextFile); - _appMap.put(originId, app); + { + OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle); + URI contextFilePath = Util.resolvePathAsLocalizedURI(contextFile, app.getBundle(), jettyHomePath); + + //set up the single context file for this deployment + app.getProperties().put(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH, contextFilePath.toString()); + + _appMap.put(app.getPath(), app); List apps = _bundleMap.get(bundle); if (apps == null) { @@ -189,9 +218,11 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu { for (App app : apps) { - _appMap.remove(app.getOriginId()); - getDeploymentManager().removeApp(app); - removed = true; + if (_appMap.remove(app.getPath()) != null) + { + getDeploymentManager().removeApp(app); + removed = true; + } } } return removed; //true if even 1 context was removed associated with this bundle diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleProvider.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleProvider.java similarity index 95% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleProvider.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleProvider.java index 3d188e9b551..10111e08556 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleProvider.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleProvider.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot; +package org.eclipse.jetty.osgi; import org.osgi.framework.Bundle; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleWebAppProvider.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleWebAppProvider.java similarity index 70% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleWebAppProvider.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleWebAppProvider.java index 772ed4c1c42..02599989be3 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleWebAppProvider.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleWebAppProvider.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot; +package org.eclipse.jetty.osgi; import java.util.Dictionary; import java.util.HashMap; @@ -19,8 +19,8 @@ import java.util.Hashtable; import java.util.Map; import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee9.osgi.boot.utils.Util; +import org.eclipse.jetty.osgi.util.Util; +import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.StringUtil; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -36,9 +36,9 @@ import org.slf4j.LoggerFactory; *

* A Jetty Provider that knows how to deploy a WebApp contained inside a Bundle. */ -public class BundleWebAppProvider extends AbstractWebAppProvider implements BundleProvider +public class BundleWebAppProvider extends AbstractContextProvider implements BundleProvider { - private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); /** * Map of Bundle to App. Used when a Bundle contains a webapp. @@ -65,6 +65,7 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund try { String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME)) || (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName)))) { @@ -93,19 +94,20 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund } } - public BundleWebAppProvider(ServerInstanceWrapper wrapper) + public BundleWebAppProvider(String environment, Server server, ContextFactory contextFactory) { - super(wrapper); + super(environment, server, contextFactory); } @Override protected void doStart() throws Exception { - _webappTracker = new WebAppTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName()); + String serverName = (String)getServer().getAttribute(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + _webappTracker = new WebAppTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), serverName); _webappTracker.open(); //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to Dictionary properties = new Hashtable<>(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); + properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName); _serviceRegForBundles = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(BundleProvider.class.getName(), this, properties); super.doStart(); } @@ -131,6 +133,29 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund super.doStop(); } + @Override + public boolean isDeployable(Bundle bundle) + { + //is it destined for my environment? + if (!super.isDeployable(bundle)) + return false; + + //has a war path, could be a webapp + if (!StringUtil.isBlank(Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, bundle.getHeaders()))) + return true; + + //has a context path header, could be a webapp + if (!StringUtil.isBlank(Util.getManifestHeaderValue(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH, bundle.getHeaders()))) + return true; + + //has a web.xml, could be a webapp + if (bundle.getEntry("/WEB-INF/web.xml") != null) + return true; + + //not a webapp + return false; + } + /** * A bundle has been added that could be a webapp * @@ -141,29 +166,27 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund { if (bundle == null) return false; + + //can this bundle be deployed to my environment? + if (!isDeployable(bundle)) + return false; ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps()); - String contextPath = null; + Thread.currentThread().setContextClassLoader((ClassLoader)getServer().getAttribute(OSGiServerConstants.SERVER_CLASSLOADER)); try { @SuppressWarnings("unchecked") Dictionary headers = bundle.getHeaders(); - + //does the bundle have a OSGiWebappConstants.JETTY_WAR_FOLDER_PATH - String resourcePath = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, headers); - if (resourcePath != null) + String staticResourcesLocation = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, headers); + if (staticResourcesLocation != null) { - String base = resourcePath; - contextPath = getContextPath(bundle); - String originId = getOriginId(bundle, base); - //TODO : we don't know whether an app is actually deployed, as deploymentManager swallows all //exceptions inside the impl of addApp. Need to send the Event and also register as a service //only if the deployment succeeded - OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId); - app.setWebAppPath(base); - app.setContextPath(contextPath); + OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle); + app.setPathToResourceBase(staticResourcesLocation); _bundleMap.put(bundle, app); getDeploymentManager().addApp(app); return true; @@ -173,12 +196,8 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund if (bundle.getEntry("/WEB-INF/web.xml") != null) { String base = "."; - contextPath = getContextPath(bundle); - String originId = getOriginId(bundle, base); - - OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId); - app.setContextPath(contextPath); - app.setWebAppPath(base); + OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle); + app.setPathToResourceBase(base); _bundleMap.put(bundle, app); getDeploymentManager().addApp(app); return true; @@ -189,24 +208,16 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund { //Could be a static webapp with no web.xml String base = "."; - contextPath = headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - String originId = getOriginId(bundle, base); - - OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId); - app.setContextPath(contextPath); - app.setWebAppPath(base); + OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle); + app.setPathToResourceBase(base); _bundleMap.put(bundle, app); getDeploymentManager().addApp(app); return true; } + //not a webapp return false; } - catch (Exception e) - { - - throw e; - } finally { Thread.currentThread().setContextClassLoader(cl); @@ -230,28 +241,4 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund } return false; } - - private static String getContextPath(Bundle bundle) - { - Dictionary headers = bundle.getHeaders(); - String contextPath = (String)headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - if (contextPath == null) - { - // extract from the last token of the bundle's location: - // (really ?could consider processing the symbolic name as an alternative - // the location will often reflect the version. - // maybe this is relevant when the file is a war) - String location = bundle.getLocation(); - String[] toks = StringUtil.replace(location, '\\', '/').split("/"); - contextPath = toks[toks.length - 1]; - // remove .jar, .war etc: - int lastDot = contextPath.lastIndexOf('.'); - if (lastDot != -1) - contextPath = contextPath.substring(0, lastDot); - } - if (!contextPath.startsWith("/")) - contextPath = "/" + contextPath; - - return contextPath; - } } diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceProvider.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/ContextFactory.java similarity index 58% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceProvider.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/ContextFactory.java index 2454c56fbc9..11034d2861b 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceProvider.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/ContextFactory.java @@ -11,19 +11,13 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot; +package org.eclipse.jetty.osgi; +import org.eclipse.jetty.deploy.App; +import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.ServiceReference; -/** - * ServiceProvider - * - * Jetty DeploymentManager Provider api for webapps or ContextHandlers that are discovered as OSGi services. - */ -public interface ServiceProvider +public interface ContextFactory { - public boolean serviceAdded(ServiceReference ref, ContextHandler handler) throws Exception; - - public boolean serviceRemoved(ServiceReference ref, ContextHandler handler) throws Exception; + ContextHandler createContextHandler(AbstractContextProvider provider, App app) throws Exception; } diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyBootstrapActivator.java similarity index 73% rename from jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyBootstrapActivator.java index a31bfdcc497..13ffddc540f 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyBootstrapActivator.java @@ -11,11 +11,13 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory; +package org.eclipse.jetty.osgi; import java.io.File; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Dictionary; import java.util.Enumeration; @@ -24,32 +26,28 @@ import java.util.List; import java.util.Map; import java.util.StringTokenizer; -import org.eclipse.jetty.ee10.osgi.boot.JettyBootstrapActivator; -import org.eclipse.jetty.ee10.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee10.osgi.boot.utils.OSGiClassLoader; -import org.eclipse.jetty.ee10.osgi.boot.utils.Util; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.OSGiClassLoader; +import org.eclipse.jetty.osgi.util.Util; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.resource.JarResource; -import org.eclipse.jetty.util.resource.Resource; import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * DefaultJettyAtJettyHomeHelper + * JettyBootstrapActivator *

- * Creates a default instance of Jetty, based on the values of the - * System properties "jetty.home" or "jetty.home.bundle", one of which - * must be specified in order to create the default instance. - *

- * Called by the {@link JettyBootstrapActivator} during the starting of the - * bundle. + * Bootstrap jetty and publish a default Server instance as an OSGi service. */ -public class DefaultJettyAtJettyHomeHelper +public class JettyBootstrapActivator implements BundleActivator { - private static final Logger LOG = LoggerFactory.getLogger(DefaultJettyAtJettyHomeHelper.class); + private static final Logger LOG = LoggerFactory.getLogger(JettyBootstrapActivator.class); + + private static JettyBootstrapActivator INSTANCE = null; /** * contains a comma separated list of paths to the etc/jetty-*.xml files @@ -66,10 +64,73 @@ public class DefaultJettyAtJettyHomeHelper */ public static final String DEFAULT_JETTYHOME = "/jettyhome"; + private ServiceRegistration _registeredServer; + /* private PackageAdminServiceTracker _packageAdminServiceTracker;*/ + /** - * Called by the JettyBootStrapActivator. If the system property jetty.home - * is defined and points to a folder, creates a corresponding jetty - * server. + * Setup a new jetty Server, register it as a service. + * + * @param context the bundle context + */ + @Override + public void start(final BundleContext context) throws Exception + { + // track other bundles and fragments attached to this bundle that we + // should activate, as OSGi will not call activators for them. + /* _packageAdminServiceTracker = new PackageAdminServiceTracker(context);*/ + + ServiceReference[] references = context.getAllServiceReferences("org.eclipse.jetty.http.HttpFieldPreEncoder", null); + + if (references == null || references.length == 0) + LOG.warn("OSGi support for java.util.ServiceLoader may not be present. You may experience runtime errors."); + + // Create a default jetty instance right now. + startJettyAtJettyHome(context); + } + + /** + * Stop the activator. + * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception + { + + /* if (_packageAdminServiceTracker != null) + { + _packageAdminServiceTracker.stop(); + context.removeServiceListener(_packageAdminServiceTracker); + _packageAdminServiceTracker = null; + } + */ + try + { + if (_registeredServer != null) + { + try + { + _registeredServer.unregister(); + } + catch (IllegalArgumentException ill) + { + // already unregistered. + } + finally + { + _registeredServer = null; + } + } + } + finally + { + INSTANCE = null; + } + } + + /** + * If the system property jetty.home is defined and points to a folder, + * creates a corresponding jetty server. *

* If the system property jetty.home.bundle is defined and points to a * bundle, look for the configuration of jetty inside that bundle. @@ -87,10 +148,9 @@ public class DefaultJettyAtJettyHomeHelper *

* * @param bundleContext the bundle context - * @return the configured server * @throws Exception if unable to create / configure / or start the server */ - public static Server startJettyAtJettyHome(BundleContext bundleContext) throws Exception + private void startJettyAtJettyHome(BundleContext bundleContext) throws Exception { String jettyHomeSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME); String jettyHomeBundleSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME_BUNDLE); @@ -112,7 +172,7 @@ public class DefaultJettyAtJettyHomeHelper if (!jettyHomeDir.exists() || !jettyHomeDir.isDirectory()) { LOG.warn("Unable to locate the jetty.home folder {}", jettyHomeSysProp); - return null; + return; } //set jetty.home @@ -135,14 +195,14 @@ public class DefaultJettyAtJettyHomeHelper if (jettyHomeBundle == null) { LOG.warn("Unable to find the jetty.home.bundle named {}", jettyHomeSysProp); - return null; + return; } } if (jettyHomeDir == null && jettyHomeBundle == null) { LOG.warn("No default jetty created."); - return null; + return; } //resolve the jetty xml config files @@ -196,15 +256,14 @@ public class DefaultJettyAtJettyHomeHelper } } - //configure the server here rather than letting the JettyServerServiceTracker do it, because we want to be able to - //configure the ThreadPool, which can only be done via the constructor, ie from within the xml configuration processing - Server server = ServerInstanceWrapper.configure(null, configURLs, properties); + //Create the default Server instance + Server defaultServer = JettyServerFactory.createServer(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME, properties, configURLs); //Register the default Server instance as an OSGi service. - //The JettyServerServiceTracker will notice it and set it up to deploy bundles as wars etc - bundleContext.registerService(Server.class.getName(), server, properties); + //The JettyServerServiceTrackers will notice it and set it up to deploy bundles as wars etc + //for each environment eg ee9,ee10, etc + _registeredServer = bundleContext.registerService(Server.class.getName(), defaultServer, properties); LOG.info("Default jetty server configured"); - return server; } catch (Exception e) { @@ -223,7 +282,7 @@ public class DefaultJettyAtJettyHomeHelper * look for the corresponding jetty configuration files that will be used to * setup the jetty server. */ - private static List getJettyConfigurationURLs(File jettyhome) + private List getJettyConfigurationURLs(File jettyhome) throws MalformedURLException { List configURLs = new ArrayList<>(); @@ -247,7 +306,7 @@ public class DefaultJettyAtJettyHomeHelper * jetty.etc.config.urls and look for the corresponding jetty configuration * files that will be used to setup the jetty server. */ - private static List getJettyConfigurationURLs(Bundle configurationBundle, Dictionary properties) + private List getJettyConfigurationURLs(Bundle configurationBundle, Dictionary properties) throws Exception { List configURLs = new ArrayList<>(); @@ -279,9 +338,9 @@ public class DefaultJettyAtJettyHomeHelper //lazily ensure jetty.home value is set based on location of etc files if (properties.get(OSGiServerConstants.JETTY_HOME) == null) { - Resource res = findDir(configurationBundle, home); - if (res != null) - properties.put(OSGiServerConstants.JETTY_HOME, res.toString()); + Path path = findDir(configurationBundle, home); + if (path != null) + properties.put(OSGiServerConstants.JETTY_HOME, path.toUri().toString()); } if (enUrls == null || !enUrls.hasMoreElements()) @@ -295,14 +354,14 @@ public class DefaultJettyAtJettyHomeHelper } /** - * Get a resource representing a directory inside a bundle. If the dir is null, - * return a resource representing the installation location of the bundle. + * Resolve a directory inside a bundle. If the dir is null, + * return a path representing the installation location of the bundle. * * @param bundle the bundle * @param dir the directory - * @return the resource found + * @return either the resolved dir inside the bundle, or the path of the bundle itself */ - public static Resource findDir(Bundle bundle, String dir) + private Path findDir(Bundle bundle, String dir) { if (bundle == null) return null; @@ -312,18 +371,12 @@ public class DefaultJettyAtJettyHomeHelper File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); URL u = f.toURI().toURL(); u = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(u); - Resource res = Resource.newResource(u); - URI ruri = res.toURI(); + Path p = Paths.get(u.toURI()); - // check if it is an unarchived bundle - if ("file".equalsIgnoreCase(ruri.getScheme()) && FileID.isJavaArchive(ruri)) - res = JarResource.newJarResource(res); - - //if looking for a directory if (dir != null) - res = res.addPath(dir); - - return res; + return p.resolve(dir); + else + return p; } catch (Exception e) { diff --git a/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyServerFactory.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyServerFactory.java new file mode 100644 index 00000000000..382d408f1a8 --- /dev/null +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyServerFactory.java @@ -0,0 +1,261 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.osgi; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.StringTokenizer; + +import org.eclipse.jetty.deploy.AppLifeCycle; +import org.eclipse.jetty.deploy.DeploymentManager; +import org.eclipse.jetty.deploy.bindings.StandardStarter; +import org.eclipse.jetty.deploy.bindings.StandardStopper; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.Util; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.eclipse.jetty.xml.XmlConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JettyServerFactory + * + * Configures a jetty Server instance. + */ +public class JettyServerFactory +{ + private static final Logger LOG = LoggerFactory.getLogger(JettyServerFactory.class.getName()); + + /** + * The value of this property points to the parent director of the jetty.xml + * configuration file currently executed. Everything is passed as a URL to + * support the case where the bundle is zipped. + */ + public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url"; + + /* + * Create a Server that is suitable for using in OSGi + */ + public static Server createServer(String name, Dictionary props, List jettyConfigurations) + throws Exception + { + Objects.requireNonNull(name); + + Server server = null; + ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); + try + { + List sharedURLs = getManagedJettySharedLibFolderUrls(props); + + // Ensure we have a classloader that will have access to all jetty classes + ClassLoader libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(null, sharedURLs, contextCl/*JettyServerFactory.class.getClassLoader()*/); + + ClassLoader serverClassLoader = libExtClassLoader; + + if (LOG.isDebugEnabled()) + LOG.debug("LibExtClassLoader = {}", libExtClassLoader); + + Thread.currentThread().setContextClassLoader(libExtClassLoader); + + //Get ready to apply jetty configuration files, both those as explicit argument, + //as well as those provided by property + List jettyConfigs = new ArrayList<>(); + if (jettyConfigurations != null) + jettyConfigs.addAll(jettyConfigurations); + + //config files provided as part of the osgi properties + String jettyConfigFilenames = (String)props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS); + if (jettyConfigFilenames != null) + { + jettyConfigs.addAll(Util.fileNamesAsURLs(jettyConfigFilenames, StringUtil.DEFAULT_DELIMS)); + } + + Map idMap = new HashMap<>(); + + Map properties = new HashMap<>(); + if (props != null) + { + Enumeration en = props.keys(); + while (en.hasMoreElements()) + { + String key = en.nextElement(); + Object value = props.get(key); + properties.put(key, value.toString()); + } + } + + try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable()) + { + //create the server via config files + for (URL jettyConfiguration : jettyConfigurations) + { + try + { + // Execute a Jetty configuration file + XmlConfiguration config = new XmlConfiguration(resourceFactory.newResource(jettyConfiguration)); + + config.getIdMap().putAll(idMap); + config.getProperties().putAll(properties); + + // #334062 compute the URL of the folder that contains the + // conf file and set it as a property so we can compute relative paths + // from it. + String urlPath = jettyConfiguration.toString(); + int lastSlash = urlPath.lastIndexOf('/'); + if (lastSlash > 4) + { + urlPath = urlPath.substring(0, lastSlash); + config.getProperties().put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath); + } + + Object o = config.configure(); + server = (Server)o; + + idMap = config.getIdMap(); + } + catch (Exception e) + { + LOG.warn("Configuration error in {}", jettyConfiguration); + throw e; + } + } + } + + //if no config files, create the server + if (server == null) + server = new Server(); + + //ensure ContextHandlerCollection + ContextHandlerCollection contextHandlerCollection = getContextHandlerCollection(server); + if (contextHandlerCollection == null) + { + contextHandlerCollection = new ContextHandlerCollection(); + server.setHandler(contextHandlerCollection); + } + + //ensure DeploymentManager + DeploymentManager deploymentManager = ensureDeploymentManager(server); + deploymentManager.setUseStandardBindings(false); + List deploymentLifeCycleBindings = new ArrayList<>(); + deploymentLifeCycleBindings.add(new OSGiDeployer(server)); + deploymentLifeCycleBindings.add(new StandardStarter()); + deploymentLifeCycleBindings.add(new StandardStopper()); + deploymentLifeCycleBindings.add(new OSGiUndeployer(server)); + deploymentManager.setLifeCycleBindings(deploymentLifeCycleBindings); + + server.setAttribute(OSGiServerConstants.JETTY_HOME, properties.get(OSGiServerConstants.JETTY_HOME)); + server.setAttribute(OSGiServerConstants.JETTY_BASE, properties.get(OSGiServerConstants.JETTY_BASE)); + server.setAttribute(OSGiServerConstants.SERVER_CLASSLOADER, serverClassLoader); + server.setAttribute(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, name); + + return server; + } + catch (Exception e) + { + if (server != null) + { + try + { + server.stop(); + } + catch (Exception x) + { + LOG.trace("IGNORED", x); + } + } + throw e; + } + finally + { + Thread.currentThread().setContextClassLoader(contextCl); + } + } + + private static DeploymentManager ensureDeploymentManager(Server server) + { + Collection deployers = server.getBeans(DeploymentManager.class); + DeploymentManager deploymentManager; + + if (deployers != null) + { + deploymentManager = deployers.stream().findFirst().get(); + } + else + { + deploymentManager = new DeploymentManager(); + deploymentManager.setContexts(getContextHandlerCollection(server)); + server.addBean(deploymentManager); + } + + return deploymentManager; + } + + private static ContextHandlerCollection getContextHandlerCollection(Server server) + { + return (ContextHandlerCollection)server.getDescendant(ContextHandlerCollection.class); + } + + /** + * Get the Jetty Shared Lib Folder URLs in a form that is suitable for + * {@link LibExtClassLoaderHelper} to use. + * + * @param props the properties to look for the configuration in + * @return the list of URLs found, or null if none found + */ + private static List getManagedJettySharedLibFolderUrls(Dictionary props) + { + String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); + if (StringUtil.isBlank(sharedURLs)) + { + return null; + } + + List libURLs = new ArrayList<>(); + + StringTokenizer tokenizer = new StringTokenizer(sharedURLs, StringUtil.DEFAULT_DELIMS, false); + while (tokenizer.hasMoreTokens()) + { + String tok = tokenizer.nextToken(); + try + { + URL url = new URL(tok); + url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(url); + if (url.getProtocol().equals("file")) + { + libURLs.add(new URL("jar:" + url.toExternalForm() + "!/")); + } + else + { + if (LOG.isDebugEnabled()) + LOG.debug("Unrecognized Jetty Shared Lib URL: {}", url); + } + } + catch (Throwable mfe) + { + LOG.warn("Unable to process legacy lib folder {}", tok, mfe); + } + } + return libURLs; + } +} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/LibExtClassLoaderHelper.java similarity index 99% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/LibExtClassLoaderHelper.java index b871a1a0e22..2ebbf27998b 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/LibExtClassLoaderHelper.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.internal.webapp; +package org.eclipse.jetty.osgi; import java.io.File; import java.net.MalformedURLException; @@ -25,6 +25,8 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import org.eclipse.jetty.util.FileID; + /** * LibExtClassLoaderHelper *

@@ -50,7 +52,6 @@ import java.util.Set; */ public class LibExtClassLoaderHelper { - /** * IFilesInJettyHomeResourcesProcessor * diff --git a/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiApp.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiApp.java new file mode 100644 index 00000000000..5b250c5552f --- /dev/null +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiApp.java @@ -0,0 +1,259 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.osgi; + +import java.io.File; +import java.net.URI; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Objects; + +import org.eclipse.jetty.deploy.App; +import org.eclipse.jetty.deploy.AppProvider; +import org.eclipse.jetty.deploy.DeploymentManager; +import org.eclipse.jetty.ee.Deployable; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.FileID; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * OSGiApp + * + * Base class representing info about a WebAppContext/ContextHandler to be deployed into jetty. + */ +public class OSGiApp extends App +{ + private static final Logger LOG = LoggerFactory.getLogger(OSGiApp.class); + + protected Bundle _bundle; + protected ServiceRegistration _registration; + protected ContextHandler _contextHandler; + protected String _pathToResourceBase; + protected String _contextPath; + protected Resource _bundleResource; + + /** + * Get the install location of a Bundle as a Path + * @param bundle the Bundle whose location to return + * @return the installed location of the Bundle as a Path + * @throws Exception + */ + private static Path getBundlePath(Bundle bundle) throws Exception + { + String bundleOverrideLocation = bundle.getHeaders().get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); + File bundleLocation = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); + File root = (bundleOverrideLocation == null ? bundleLocation : new File(bundleOverrideLocation)); + return Paths.get(root.toURI()); + + } + + /** + * Convert a bundle installed location into a Resource, taking account of + * any locations that are actually packed jars, but without a ".jar" extension, eg + * as found on equinox. Eg file:///a/b/c/org.eclipse.osgi/89/0/bundleFile + * @param bundle the bundle + * @return a Resource representing the bundle's installed location + * @throws Exception + */ + private static Resource getBundleAsResource(Bundle bundle) throws Exception + { + String bundleOverrideLocation = bundle.getHeaders().get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); + File bundleLocation = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); + File root = (bundleOverrideLocation == null ? bundleLocation : new File(bundleOverrideLocation)); + //Fix some osgiPaths.get( locations which point to an archive, but that doesn't end in .jar + URL url = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(root.toURI().toURL()); + + return ResourceFactory.root().newResource(url); + } + + /** + * Get or create a contextPath from bundle headers and information + * + * @param bundle + * @return a contextPath + */ + private static String getContextPath(Bundle bundle) + { + Dictionary headers = bundle.getHeaders(); + String contextPath = (String)headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); + if (contextPath == null) + { + // extract from the last token of the bundle's location: + // (really ?could consider processing the symbolic name as an alternative + // the location will often reflect the version. + // maybe this is relevant when the file is a war) + String location = bundle.getLocation(); + String[] toks = StringUtil.replace(location, '\\', '/').split("/"); + contextPath = toks[toks.length - 1]; + // remove .jar, .war etc: + int lastDot = contextPath.lastIndexOf('.'); + if (lastDot != -1) + contextPath = contextPath.substring(0, lastDot); + } + if (!contextPath.startsWith("/")) + contextPath = "/" + contextPath; + + return contextPath; + } + + /** + * @param manager the DeploymentManager to which to deploy + * @param provider the provider that discovered the context/webapp + * @param bundle the bundle associated with the context/webapp + */ + public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle) + throws Exception + { + super(manager, provider, getBundlePath(bundle)); + + _bundle = Objects.requireNonNull(bundle); + _bundleResource = getBundleAsResource(bundle); + + //copy selected bundle headers into the properties + Dictionary headers = bundle.getHeaders(); + Enumeration keys = headers.keys(); + while (keys.hasMoreElements()) + { + String key = keys.nextElement(); + String val = headers.get(key); + if (Deployable.ENVIRONMENT.equalsIgnoreCase(key) || OSGiWebappConstants.JETTY_ENVIRONMENT.equalsIgnoreCase(key)) + getProperties().put(Deployable.ENVIRONMENT, val); + else if (Deployable.DEFAULTS_DESCRIPTOR.equalsIgnoreCase(key) || OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH.equalsIgnoreCase(key)) + { + getProperties().put(Deployable.DEFAULTS_DESCRIPTOR, val); + } + else if (OSGiWebappConstants.JETTY_WEB_XML_PATH.equalsIgnoreCase(key)) + { + getProperties().put(key, val); + } + else if (OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH.equalsIgnoreCase(key)) + { + getProperties().put(key, val); + } + } + + //set up the context path based on the supplied value, or the calculated default + setContextPath(getContextPath(bundle)); + } + + public Resource getBundleResource() + { + return _bundleResource; + } + + @Override + public ContextHandler getContextHandler() throws Exception + { + if (_contextHandler == null) + _contextHandler = getAppProvider().createContextHandler(this); + return _contextHandler; + } + + public void setContextHandler(ContextHandler contextHandler) + { + _contextHandler = contextHandler; + } + + public String getPathToResourceBase() + { + return _pathToResourceBase; + } + + public void setPathToResourceBase(String path) + { + _pathToResourceBase = path; + } + + @Override + public String getContextPath() + { + return _contextPath; + } + + public void setContextPath(String contextPath) + { + _contextPath = contextPath; + } + + public String getBundleSymbolicName() + { + return _bundle.getSymbolicName(); + } + + public String getBundleVersionAsString() + { + if (_bundle.getVersion() == null) + return null; + return _bundle.getVersion().toString(); + } + + public Bundle getBundle() + { + return _bundle; + } + + public void setRegistration(ServiceRegistration registration) + { + _registration = registration; + } + + public ServiceRegistration getRegistration() + { + return _registration; + } + + /** + * Register the Jetty deployed context/webapp as a service, as + * according to the OSGi Web Application Specification. + * + * @throws Exception + */ + public void registerAsOSGiService() throws Exception + { + if (_registration == null) + { + Dictionary properties = new Hashtable(); + properties.put(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK); + if (getBundleSymbolicName() != null) + properties.put(OSGiWebappConstants.OSGI_WEB_SYMBOLICNAME, getBundleSymbolicName()); + if (getBundleVersionAsString() != null) + properties.put(OSGiWebappConstants.OSGI_WEB_VERSION, getBundleVersionAsString()); + properties.put(OSGiWebappConstants.OSGI_WEB_CONTEXTPATH, getContextPath()); + ServiceRegistration rego = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ContextHandler.class.getName(), getContextHandler(), properties); + setRegistration(rego); + } + } + + protected void deregisterAsOSGiService() throws Exception + { + if (_registration == null) + return; + + _registration.unregister(); + _registration = null; + } +} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiDeployer.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiDeployer.java similarity index 74% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiDeployer.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiDeployer.java index eecf0d83385..1290aae8ef7 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiDeployer.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiDeployer.java @@ -11,13 +11,13 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot; +package org.eclipse.jetty.osgi; import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.bindings.StandardDeployer; import org.eclipse.jetty.deploy.graph.Node; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee9.osgi.boot.utils.EventSender; +import org.eclipse.jetty.osgi.util.EventSender; +import org.eclipse.jetty.server.Server; /** * OSGiDeployer @@ -28,9 +28,9 @@ import org.eclipse.jetty.ee9.osgi.boot.utils.EventSender; public class OSGiDeployer extends StandardDeployer { - private ServerInstanceWrapper _server; + private Server _server; - public OSGiDeployer(ServerInstanceWrapper server) + public OSGiDeployer(Server server) { _server = server; } @@ -40,22 +40,22 @@ public class OSGiDeployer extends StandardDeployer { //TODO how to NOT send this event if its not a webapp: //OSGi Enterprise Spec only wants an event sent if its a webapp bundle (ie not a ContextHandler) - if (!(app instanceof AbstractOSGiApp)) + if (!(app instanceof OSGiApp)) { doProcessBinding(node, app); } else { - EventSender.getInstance().send(EventSender.DEPLOYING_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); + EventSender.getInstance().send(EventSender.DEPLOYING_EVENT, ((OSGiApp)app).getBundle(), app.getContextPath()); try { doProcessBinding(node, app); - ((AbstractOSGiApp)app).registerAsOSGiService(); - EventSender.getInstance().send(EventSender.DEPLOYED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); + ((OSGiApp)app).registerAsOSGiService(); + EventSender.getInstance().send(EventSender.DEPLOYED_EVENT, ((OSGiApp)app).getBundle(), app.getContextPath()); } catch (Exception e) { - EventSender.getInstance().send(EventSender.FAILED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); + EventSender.getInstance().send(EventSender.FAILED_EVENT, ((OSGiApp)app).getBundle(), app.getContextPath()); throw e; } } @@ -64,7 +64,8 @@ public class OSGiDeployer extends StandardDeployer protected void doProcessBinding(Node node, App app) throws Exception { ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(_server.getParentClassLoaderForWebapps()); + ClassLoader cl = (ClassLoader)_server.getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + Thread.currentThread().setContextClassLoader(cl); try { super.processBinding(node, app); diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiServerConstants.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiServerConstants.java similarity index 86% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiServerConstants.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiServerConstants.java index d690d729900..52287dfb455 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiServerConstants.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiServerConstants.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot; +package org.eclipse.jetty.osgi; /** * OSGiServerConstants @@ -19,7 +19,7 @@ package org.eclipse.jetty.ee9.osgi.boot; * Name of the properties that configure a jetty Server OSGi service. */ public class OSGiServerConstants -{ +{ /** * Usual system property used as the hostname for a typical jetty * configuration. @@ -80,4 +80,15 @@ public class OSGiServerConstants * List of URLs to the folders where the legacy J2EE shared libraries are stored aka lib/ext, lib/jsp etc. */ public static final String MANAGED_JETTY_SHARED_LIB_FOLDER_URLS = "managedJettySharedLibFolderUrls"; + + /* + * Name of server attribute that stores a classloader suitable as the parent classloader for contexts + */ + public static final String SERVER_CLASSLOADER = "org.eclipse.jetty.osgi.server.classLoader"; + + /** + * Name of server attribute that stores a List of Bundles on the server classpath that must be scanned + */ + public static final String SERVER_CLASSPATH_BUNDLES = "org.eclipse.jetty.osgi.server.classpathBundles"; + } diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiUndeployer.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiUndeployer.java similarity index 71% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiUndeployer.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiUndeployer.java index 8ad01ab59d7..6399ffb883b 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiUndeployer.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiUndeployer.java @@ -11,13 +11,13 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot; +package org.eclipse.jetty.osgi; import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.bindings.StandardUndeployer; import org.eclipse.jetty.deploy.graph.Node; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee9.osgi.boot.utils.EventSender; +import org.eclipse.jetty.osgi.util.EventSender; +import org.eclipse.jetty.server.Server; /** * OSGiUndeployer @@ -27,9 +27,9 @@ import org.eclipse.jetty.ee9.osgi.boot.utils.EventSender; */ public class OSGiUndeployer extends StandardUndeployer { - private ServerInstanceWrapper _server; + private Server _server; - public OSGiUndeployer(ServerInstanceWrapper server) + public OSGiUndeployer(Server server) { _server = server; } @@ -37,9 +37,10 @@ public class OSGiUndeployer extends StandardUndeployer @Override public void processBinding(Node node, App app) throws Exception { - EventSender.getInstance().send(EventSender.UNDEPLOYING_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); + EventSender.getInstance().send(EventSender.UNDEPLOYING_EVENT, ((OSGiApp)app).getBundle(), app.getContextPath()); ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(_server.getParentClassLoaderForWebapps()); + ClassLoader cl = (ClassLoader)_server.getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + Thread.currentThread().setContextClassLoader(cl); try { super.processBinding(node, app); @@ -48,7 +49,7 @@ public class OSGiUndeployer extends StandardUndeployer { Thread.currentThread().setContextClassLoader(old); } - EventSender.getInstance().send(EventSender.UNDEPLOYED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); - ((AbstractOSGiApp)app).deregisterAsOSGiService(); + EventSender.getInstance().send(EventSender.UNDEPLOYED_EVENT, ((OSGiApp)app).getBundle(), app.getContextPath()); + ((OSGiApp)app).deregisterAsOSGiService(); } } diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebappConstants.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiWebappConstants.java similarity index 94% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebappConstants.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiWebappConstants.java index 5d0a543896b..828f8d7bee1 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebappConstants.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiWebappConstants.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot; +package org.eclipse.jetty.osgi; /** * OSGiWebappConstants @@ -70,7 +70,7 @@ public class OSGiWebappConstants public static final String JETTY_OSGI_BUNDLE = "osgi-bundle"; /** - * List of relative pathes within the bundle to the jetty context files. + * List of relative paths within the bundle to the jetty context files. */ public static final String JETTY_CONTEXT_FILE_PATH = "Jetty-ContextFilePath"; @@ -118,6 +118,11 @@ public class OSGiWebappConstants * that are in fact not embedded in a bundle */ public static final String JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE = "Jetty-bundleInstall"; + + /** + * Property naming the environment (eg ee8/ee9/ee10 etc) + */ + public static final String JETTY_ENVIRONMENT = "Jetty-Environment"; /** * Comma separated list of bundles that contain tld file used by the webapp. diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleClassLoaderHelper.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelper.java similarity index 87% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleClassLoaderHelper.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelper.java index 6a6c745f202..0346b31bfb9 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleClassLoaderHelper.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelper.java @@ -11,9 +11,8 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; -import org.eclipse.jetty.ee9.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper; import org.osgi.framework.Bundle; /** @@ -37,7 +36,7 @@ public interface BundleClassLoaderHelper /** * The name of the custom implementation for this interface in a fragment. */ - public static final String CLASS_NAME = "org.eclipse.jetty.ee9.osgi.boot.utils.BundleClassLoaderHelperImpl"; + public static final String CLASS_NAME = "org.eclipse.jetty.osgi.util.BundleClassLoaderHelperImpl"; /** * The default instance supports felix and equinox diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleClassLoaderHelperFactory.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelperFactory.java similarity index 97% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleClassLoaderHelperFactory.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelperFactory.java index a9c711d5799..c85617d61b8 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleClassLoaderHelperFactory.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelperFactory.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleFileLocatorHelper.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelper.java similarity index 94% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleFileLocatorHelper.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelper.java index a8165eaaaab..baa2018d4ff 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleFileLocatorHelper.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelper.java @@ -11,13 +11,12 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; import java.io.File; import java.net.URL; import java.util.Enumeration; -import org.eclipse.jetty.ee9.osgi.boot.utils.internal.DefaultFileLocatorHelper; import org.osgi.framework.Bundle; /** @@ -32,7 +31,7 @@ public interface BundleFileLocatorHelper /** * The name of the custom implementation for this interface in a fragment. */ - public static final String CLASS_NAME = "org.eclipse.jetty.ee9.osgi.boot.utils.FileLocatorHelperImpl"; + public static final String CLASS_NAME = "org.eclipse.jetty.osgi.util.FileLocatorHelperImpl"; /** * The default instance supports felix and equinox diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleFileLocatorHelperFactory.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelperFactory.java similarity index 97% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleFileLocatorHelperFactory.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelperFactory.java index 16a712e6073..f6cbb4aae0c 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/BundleFileLocatorHelperFactory.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelperFactory.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultBundleClassLoaderHelper.java similarity index 99% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultBundleClassLoaderHelper.java index 24751a23f0a..026ed6b22af 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultBundleClassLoaderHelper.java @@ -11,13 +11,12 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils.internal; +package org.eclipse.jetty.osgi.util; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.List; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleClassLoaderHelper; import org.osgi.framework.Bundle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultFileLocatorHelper.java similarity index 95% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/DefaultFileLocatorHelper.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultFileLocatorHelper.java index 347da5d2a64..5f3946bedaa 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/DefaultFileLocatorHelper.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultFileLocatorHelper.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils.internal; +package org.eclipse.jetty.osgi.util; import java.io.File; import java.lang.reflect.Field; @@ -20,14 +20,13 @@ import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Enumeration; import java.util.zip.ZipFile; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleFileLocatorHelper; +import org.eclipse.jetty.util.FileID; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.resource.PathResource; -import org.eclipse.jetty.util.resource.Resource; import org.osgi.framework.Bundle; /** @@ -103,7 +102,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper // some osgi frameworks do use the file protocol directly in some // situations. Do use the PathResource to transform the URL into a // File: URL#toURI is broken - return new PathResource(url).getFile().getParentFile().getParentFile().getCanonicalFile(); + return Paths.get(url.toURI()).getParent().getParent().toFile(); } else if (url.getProtocol().equals("bundleentry")) { @@ -112,7 +111,6 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper // the File URLConnection con = url.openConnection(); - con.setUseCaches(Resource.getDefaultUseCaches()); // work around // problems where // url connections // cache @@ -141,7 +139,6 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper url = bundle.getEntry("/"); con = url.openConnection(); - con.setDefaultUseCaches(Resource.getDefaultUseCaches()); if (BUNDLE_ENTRY_FIELD == null) { @@ -334,7 +331,6 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper { URLConnection conn = url.openConnection(); - conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); if (BUNDLE_URL_CONNECTION_getLocalURL == null && match(conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES)) { BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL"); @@ -369,7 +365,6 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper { URLConnection conn = url.openConnection(); - conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); if (BUNDLE_URL_CONNECTION_getFileURL == null && match(conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES)) { BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL"); diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/EventSender.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/EventSender.java similarity index 98% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/EventSender.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/EventSender.java index 6c00a68e8d9..5b4fb0c0c56 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/EventSender.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/EventSender.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; import java.util.Dictionary; import java.util.Hashtable; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/FakeURLClassLoader.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/FakeURLClassLoader.java similarity index 97% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/FakeURLClassLoader.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/FakeURLClassLoader.java index 950cdf1beff..e6fdd2067d2 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/FakeURLClassLoader.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/FakeURLClassLoader.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; import java.net.URL; import java.net.URLClassLoader; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/OSGiClassLoader.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/OSGiClassLoader.java similarity index 98% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/OSGiClassLoader.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/OSGiClassLoader.java index 8ab83e24e7d..dc4227c2816 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/OSGiClassLoader.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/OSGiClassLoader.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; import java.io.IOException; import java.net.URL; diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleProvider.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerClasspathContributor.java similarity index 62% rename from jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleProvider.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerClasspathContributor.java index e86fc0d88eb..14615d77d6a 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleProvider.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerClasspathContributor.java @@ -11,18 +11,19 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.osgi.boot; +package org.eclipse.jetty.osgi.util; + +import java.util.List; import org.osgi.framework.Bundle; -/** - * BundleProvider - * - * Jetty DeploymentManager Provider api for webapps or ContextHandlers that are discovered as osgi bundles. - */ -public interface BundleProvider +public interface ServerClasspathContributor { - public boolean bundleAdded(Bundle bundle) throws Exception; - - public boolean bundleRemoved(Bundle bundle) throws Exception; + /** + * Get bundles that should be on the Server classpath, + * and should be scanned for annotations/tlds/resources etc + * + * @return list of Bundles to be scanned and put on server classpath + */ + List getScannableBundles(); } diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/ServerConnectorListener.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerConnectorListener.java similarity index 98% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/ServerConnectorListener.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerConnectorListener.java index 10c00d7ab6f..ecbc6a26b0b 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/ServerConnectorListener.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerConnectorListener.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; import java.io.FileWriter; import java.nio.file.Files; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/Util.java b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/Util.java similarity index 59% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/Util.java rename to jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/Util.java index 291ae618a7f..d3d17afb33a 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/Util.java +++ b/jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/Util.java @@ -11,25 +11,138 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils; +package org.eclipse.jetty.osgi.util; +import java.io.File; +import java.net.URI; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collections; import java.util.Dictionary; import java.util.List; +import java.util.Objects; import java.util.StringTokenizer; -import org.eclipse.jetty.ee9.osgi.boot.OSGiServerConstants; +import org.eclipse.jetty.osgi.OSGiServerConstants; import org.eclipse.jetty.util.StringUtil; +import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.packageadmin.PackageAdmin; /** * Various useful functions utility methods for OSGi wide use. */ public class Util { + /** + * Resolve a path either absolutely or against the bundle install location, or + * against jetty home. + * + * @param path the path to resolve + * @param bundle the bundle + * @param jettyHome the path to jetty home + * @return the URI within the bundle as a usable URI + */ + public static URI resolvePathAsLocalizedURI(String path, Bundle bundle, Path jettyHome) + throws Exception + { + if (StringUtil.isBlank(path)) + return null; + + if (path.startsWith("/") || path.startsWith("file:/")) //absolute location + return Paths.get(path).toUri(); + + //relative location + //try inside the bundle first + if (bundle != null) + { + URL url = bundle.getEntry(path); + if (url != null) + { + return BundleFileLocatorHelper.DEFAULT.getLocalURL(url).toURI(); + } + } + + //try resolving against jetty.home + if (jettyHome != null) + { + Path p = jettyHome.resolve(path); + if (Files.exists(p)) + return p.toUri(); + } + + return null; + } + + public static URL getLocalURL(URL url) + throws Exception + { + if (url == null) + return null; + + return BundleFileLocatorHelper.DEFAULT.getLocalURL(url); + } + + public static URL getLocalizedEntry(String file, Bundle bundle) + throws Exception + { + if (file == null || bundle == null) + return null; + + URL url = bundle.getEntry(file); + if (url == null) + return null; + + return BundleFileLocatorHelper.DEFAULT.getLocalURL(url); + } + + /** + * Resolve the file system paths to bundles identified by their symbolic names. + * + * @param bundleSymbolicNames comma separated list of symbolic bundle names + * @param bundleContext the bundle on whose behalf to resolve + * @return List of resolved Paths matching the bundle symbolic names + * + * @throws Exception + */ + public static List getPathsToBundlesBySymbolicNames(String bundleSymbolicNames, BundleContext bundleContext) + throws Exception + { + if (bundleSymbolicNames == null) + return Collections.emptyList(); + + Objects.requireNonNull(bundleContext); + + ServiceReference ref = bundleContext.getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName()); + PackageAdmin packageAdmin = (ref == null) ? null : (PackageAdmin)bundleContext.getService(ref); + if (packageAdmin == null) + throw new IllegalStateException("Unable to get PackageAdmin reference to locate required Tld bundles"); + + List paths = new ArrayList<>(); + String[] symbNames = bundleSymbolicNames.split("[, ]"); + + for (String symbName : symbNames) + { + Bundle[] bs = packageAdmin.getBundles(symbName, null); + if (bs == null || bs.length == 0) + { + throw new IllegalArgumentException("Unable to locate the bundle '" + symbName + "' specified in manifest of " + + bundleContext.getBundle().getSymbolicName()); + } + + File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bs[0]); + paths.add(f.toPath()); + } + + return paths; + } + /** * Create an osgi filter for the given classname and server name. * diff --git a/jetty-core/pom.xml b/jetty-core/pom.xml index 007f096dc3b..4b464fba0c8 100644 --- a/jetty-core/pom.xml +++ b/jetty-core/pom.xml @@ -28,6 +28,7 @@ jetty-jmx jetty-jndi jetty-keystore + jetty-osgi jetty-proxy jetty-quic jetty-rewrite @@ -51,11 +52,6 @@ jetty-jakarta-servlet-api 5.0.2 - - org.eclipse.jetty.ee9 - jetty-ee9-webapp - ${project.version} - diff --git a/jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationParser.java b/jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationParser.java index cb6913a6d63..5c1b8600d18 100644 --- a/jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationParser.java +++ b/jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationParser.java @@ -546,7 +546,7 @@ public class AnnotationParser { if (r == null) return; - + if (!r.exists()) return; @@ -578,7 +578,7 @@ public class AnnotationParser * @param dirResource the resource representing the baseResource being scanned (jar, dir, etc) * @throws Exception if unable to parse */ - private void parseDir(Set handlers, Resource dirResource) throws Exception + protected void parseDir(Set handlers, Resource dirResource) throws Exception { Path dir = dirResource.getPath(); @@ -617,13 +617,13 @@ public class AnnotationParser * @param jarResource the jar resource to parse * @throws Exception if unable to parse */ - private void parseJar(Set handlers, Resource jarResource) throws Exception + protected void parseJar(Set handlers, Resource jarResource) throws Exception { if (jarResource == null) return; - if (!FileID.isJavaArchive(jarResource.getPath())) - return; + /* if (!FileID.isJavaArchive(jarResource.getPath())) + return;*/ if (LOG.isDebugEnabled()) LOG.debug("Scanning jar {}", jarResource); @@ -643,7 +643,7 @@ public class AnnotationParser * @param classFile the class file to parse * @throws IOException if unable to parse */ - private void parseClass(Set handlers, Resource containingResource, Path classFile) throws IOException + protected void parseClass(Set handlers, Resource containingResource, Path classFile) throws IOException { if (LOG.isDebugEnabled()) LOG.debug("Parse class from {}", classFile.toUri()); diff --git a/jetty-ee10/jetty-ee10-apache-jsp/pom.xml b/jetty-ee10/jetty-ee10-apache-jsp/pom.xml index 8defa366e04..0f0b5049d3e 100644 --- a/jetty-ee10/jetty-ee10-apache-jsp/pom.xml +++ b/jetty-ee10/jetty-ee10-apache-jsp/pom.xml @@ -24,7 +24,7 @@ Jetty-specific ServletContainerInitializer for Jasper - org.eclipse.jetty.ee10.apache.jsp.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}", org.eclipse.jetty.jsp.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + org.eclipse.jetty.ee10.apache.jsp.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}", org.eclipse.jetty.ee10.jsp.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/pom.xml b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/pom.xml index 92cf92d980c..18324f7e2bf 100644 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/pom.xml +++ b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/pom.xml @@ -64,13 +64,14 @@ !org.example* - / + /ee10-demo-jetty .,WEB-INF/classes + ee10 diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/pom.xml b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/pom.xml index 778792b0872..c234f21bafe 100644 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/pom.xml +++ b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/pom.xml @@ -28,8 +28,9 @@ jakarta.servlet.jsp.*;version="[3,4)",org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))",* !org.example.* - /demo-jsp + /ee10-demo-jsp .,WEB-INF/classes + ee10 diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/pom.xml b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/pom.xml index 4298607560c..ca2f6d2f1bc 100644 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/pom.xml +++ b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/pom.xml @@ -70,9 +70,10 @@ <_nouses /> org.example.test;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}";-noimport:=true - / + /ee10-demo-spec .,WEB-INF/classes,WEB-INF/lib - /META-INF/plugin-context.xml + META-INF/plugin-context.xml + ee10 diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/annotations-context-header.xml b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/annotations-context-header.xml index 780b074db39..9ab2f3a6324 100644 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/annotations-context-header.xml +++ b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/annotations-context-header.xml @@ -16,12 +16,12 @@ - /test-spec.war + /ee10-demo-spec.war true - + Test Realm /etc/realm.properties diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/env-definitions.xml b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/env-definitions.xml index 3bc12268a27..b1efefabf33 100644 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/env-definitions.xml +++ b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/templates/env-definitions.xml @@ -1,5 +1,5 @@ - + maxAmount 100 @@ -7,7 +7,7 @@ - + jdbc/mydatasource diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/pom.xml b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/pom.xml index 759caa88e3a..ed2b3062af2 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/pom.xml +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/pom.xml @@ -10,7 +10,7 @@ Jetty OSGi Boot JSP bundle ${project.groupId}.boot.jsp - org.eclipse.jetty.ee10.osgi.boot.jasper.*,org.eclipse.jetty.ee10.osgi.boot.jsp.* + org.eclipse.jetty.ee10.osgi.boot.jsp.* @@ -73,7 +73,6 @@ Jetty-OSGi-Jasper Integration org.eclipse.jetty.ee10.osgi.boot - !org.eclipse.jetty.ee10.osgi.boot.* ${osgi.slf4j.import.packages}, org.eclipse.jdt.*;resolution:=optional, @@ -82,9 +81,9 @@ com.sun.el.lang;resolution:=optional, com.sun.el.parser;resolution:=optional, com.sun.el.util;resolution:=optional, - jakarta.el;version="[4.0,5.0)", - jakarta.servlet;version="[$(version;==;${servletImpl.osgiVersion}),$(version;+;${servletImpl.osgiVersion}))", - jakarta.servlet.resources;version="[$(version;==;${servletImpl.osgiVersion}),$(version;+;${servletImpl.osgiVersion}))", + jakarta.el;version="[5.0,6.0)", + jakarta.servlet;version="[$(version;==;${jakarta.servlet.api.version}),$(version;+;${jakarta.servlet.api.version}))", + jakarta.servlet.resources;version="[$(version;==;${jakarta.servlet.api.version}),$(version;+;${jakarta.servlet.api.version}))", jakarta.servlet.jsp.resources;version="[$(version;==;${jakarta.servlet.jsp.api.version}),$(version;+;${jakarta.servlet.jsp.api.version}))", jakarta.servlet.jsp;version="[$(version;==;${jakarta.servlet.jsp.api.version}),$(version;+;${jakarta.servlet.jsp.api.version}))", jakarta.servlet.jsp.el;version="[$(version;==;${jakarta.servlet.jsp.api.version}),$(version;+;${jakarta.servlet.jsp.api.version}))", @@ -100,6 +99,7 @@ org.apache.el.parser;version="[$(version;==;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))";resolution:=optional, org.apache.jasper;version="[$(version;==;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))";resolution:=optional, org.apache.jasper.compiler;version="[$(version;==;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))";resolution:=optional, + org.apache.jasper.compiler.util;version="[$(version;==;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))";resolution:=optional, org.apache.jasper.compiler.tagplugin;version="[$(version;==;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))";resolution:=optional, org.apache.jasper.runtime;version="[$(version;==;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))";resolution:=optional, org.apache.jasper.security;version="[$(version;==;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))";resolution:=optional, @@ -131,7 +131,7 @@ org.apache.taglibs.standard.tei;version="2.0";resolution:=optional, org.apache.taglibs.standard.tlv;version="2.0";resolution:=optional, org.apache.tomcat;version="[10,11)";resolution:=optional, - org.eclipse.jetty.jsp;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))";resolution:=optional, + org.eclipse.jetty.ee10.jsp;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))";resolution:=optional, org.osgi.*, org.xml.*;resolution:=optional, org.xml.sax.*;resolution:=optional, @@ -140,7 +140,7 @@ org.w3c.dom.ls;resolution:=optional, javax.xml.parser;resolution:=optional - org.eclipse.jetty.jsp.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))", + org.eclipse.jetty.ee10.jsp.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))", org.apache.jasper.*;version="[$(version;===;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))", org.apache.el.*;version="[$(version;===;${jspImpl.osgiVersion}),$(version;+;${jspImpl.osgiVersion}))" diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/ContainerTldBundleDiscoverer.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/ContainerTldBundleDiscoverer.java deleted file mode 100644 index 91899b68326..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/ContainerTldBundleDiscoverer.java +++ /dev/null @@ -1,249 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.jasper; - -import java.io.File; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.regex.Pattern; - -import jakarta.servlet.jsp.JspFactory; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee10.osgi.boot.JettyBootstrapActivator; -import org.eclipse.jetty.ee10.osgi.boot.OSGiMetaInfConfiguration; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelper; -import org.eclipse.jetty.ee10.osgi.boot.utils.TldBundleDiscoverer; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ContainerTldBundleDiscoverer - * - * Finds bundles that are considered as on the container classpath that - * contain tlds. - * - * The System property org.eclipse.jetty.ee10.osgi.tldbundles is a comma - * separated list of exact symbolic names of bundles that have container classpath - * tlds. - * - * The DeploymentManager context attribute "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern" - * can be used to define a pattern of symbolic names of bundles that contain container - * classpath tlds. - * - * The matching bundles are converted to URLs that are put onto a special classloader that acts as the - * parent classloader for contexts deployed by the jetty Server instance (see ServerInstanceWrapper). - * - * It also discovers the bundle that contains the jstl taglib and adds it into the - * "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern" (if it is not already there) so - * that the WebInfOSGiConfiguration class will add the jstl taglib bundle into the list of container - * resources. - * - * Eg: - * -Dorg.eclipse.jetty.ee10.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh - */ -public class ContainerTldBundleDiscoverer implements TldBundleDiscoverer -{ - - private static final Logger LOG = LoggerFactory.getLogger(ContainerTldBundleDiscoverer.class); - - private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl"; - /** - * Default name of a class that belongs to the jstl bundle. From that class - * we locate the corresponding bundle and register it as a bundle that - * contains tld files. - */ - private static String DEFAULT_JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.rt.core.WhenTag"; - - private Bundle jstlBundle = null; - - /** - * Check the System property "org.eclipse.jetty.ee10.osgi.tldbundles" for names of - * bundles that contain tlds and convert to URLs. - * - * @return The location of the jars that contain tld files as URLs. - */ - @Override - public URL[] getUrlsForBundlesWithTlds(DeploymentManager deploymentManager, BundleFileLocatorHelper locatorHelper) throws Exception - { - if (!isJspAvailable()) - { - return new URL[0]; - } - - if (jstlBundle == null) - jstlBundle = findJstlBundle(); - - final Bundle[] bundles = FrameworkUtil.getBundle(ContainerTldBundleDiscoverer.class).getBundleContext().getBundles(); - HashSet urls = new HashSet(); - String tmp = System.getProperty(OSGiMetaInfConfiguration.SYS_PROP_TLD_BUNDLES); //comma separated exact names - List sysNames = new ArrayList(); - if (tmp != null) - { - StringTokenizer tokenizer = new StringTokenizer(tmp, ", \n\r\t", false); - while (tokenizer.hasMoreTokens()) - { - sysNames.add(tokenizer.nextToken()); - } - } - tmp = (String)deploymentManager.getContextAttribute(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN); //bundle name patterns - - Pattern pattern = (tmp == null ? null : Pattern.compile(tmp)); - - //check that the jstl bundle is not already included in the pattern, and include it if it is not because - //subsequent classes such as OSGiWebInfConfiguration use this pattern to determine which jars are - //considered to be on the container classpath - if (jstlBundle != null) - { - if (pattern == null) - { - pattern = Pattern.compile(jstlBundle.getSymbolicName()); - deploymentManager.setContextAttribute(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, jstlBundle.getSymbolicName()); - } - else if (!(pattern.matcher(jstlBundle.getSymbolicName()).matches())) - { - String s = tmp + "|" + jstlBundle.getSymbolicName(); - pattern = Pattern.compile(s); - deploymentManager.setContextAttribute(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, s); - } - } - - for (Bundle bundle : bundles) - { - if (sysNames.contains(bundle.getSymbolicName())) - convertBundleLocationToURL(locatorHelper, bundle, urls); - else if (pattern != null && pattern.matcher(bundle.getSymbolicName()).matches()) - convertBundleLocationToURL(locatorHelper, bundle, urls); - } - - return urls.toArray(new URL[urls.size()]); - } - - /** - * Check that jsp is on the classpath - * - * @return true if jsp is available in the environment - */ - public boolean isJspAvailable() - { - try - { - getClass().getClassLoader().loadClass("org.apache.jasper.servlet.JspServlet"); - } - catch (Exception e) - { - LOG.warn("Unable to locate the JspServlet: jsp support unavailable.", e); - return false; - } - return true; - } - - /** - * Some versions of JspFactory do Class.forName, which probably won't work in an - * OSGi environment. - */ - public void fixJspFactory() - { - try - { - Class servletContextClass = jakarta.servlet.ServletContext.class; - // bug #299733 - JspFactory fact = JspFactory.getDefaultFactory(); - if (fact == null) - { // bug #299733 - // JspFactory does a simple - // Class.getForName("org.apache.jasper.runtime.JspFactoryImpl") - // however its bundles does not import the jasper package - // so it fails. let's help things out: - fact = (JspFactory)JettyBootstrapActivator.class.getClassLoader() - .loadClass(DEFAULT_JSP_FACTORY_IMPL_CLASS).getDeclaredConstructor().newInstance(); - JspFactory.setDefaultFactory(fact); - } - } - catch (Exception e) - { - LOG.warn("Unable to set the JspFactory: jsp support incomplete.", e); - } - } - - /** - * Find the bundle that contains a jstl implementation class, which assumes that - * the jstl taglibs will be inside the same bundle. - * - * @return Bundle contains the jstl implementation class - */ - public Bundle findJstlBundle() - { - Class jstlClass = null; - - try - { - jstlClass = JSTLBundleDiscoverer.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS); - } - catch (ClassNotFoundException e) - { - LOG.info("jstl not on classpath", e); - } - - if (jstlClass != null) - //get the bundle containing jstl - return FrameworkUtil.getBundle(jstlClass); - - return null; - } - - /** - * Resolves a bundle that contains tld files as a URL. The URLs are - * used by jasper to discover the tld files. - * - * Support only 2 types of packaging for the bundle: - the bundle is a jar - * (recommended for runtime.) - the bundle is a folder and contain jars in - * the root and/or in the lib folder (nice for PDE development situations) - * Unsupported: the bundle is a jar that embeds more jars. - */ - private void convertBundleLocationToURL(BundleFileLocatorHelper locatorHelper, Bundle bundle, Set urls) throws Exception - { - File jasperLocation = locatorHelper.getBundleInstallLocation(bundle); - if (jasperLocation.isDirectory()) - { - for (File f : jasperLocation.listFiles()) - { - if (FileID.isJavaArchive(f.getName()) && f.isFile()) - { - urls.add(f.toURI().toURL()); - } - else if (f.isDirectory() && f.getName().equals("lib")) - { - for (File f2 : jasperLocation.listFiles()) - { - if (FileID.isJavaArchive(f2.getName()) && f2.isFile()) - { - urls.add(f2.toURI().toURL()); - } - } - } - } - urls.add(jasperLocation.toURI().toURL()); - } - else - { - urls.add(jasperLocation.toURI().toURL()); - } - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/JSTLBundleDiscoverer.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/JSTLBundleDiscoverer.java deleted file mode 100644 index e4beaba7fee..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jasper/JSTLBundleDiscoverer.java +++ /dev/null @@ -1,178 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.jasper; - -import java.io.File; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -import jakarta.servlet.jsp.JspFactory; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee10.osgi.boot.JettyBootstrapActivator; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelper; -import org.eclipse.jetty.ee10.osgi.boot.utils.TldBundleDiscoverer; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JSTLBundleDiscoverer - * - * Fix various shortcomings with the way jasper parses the tld files. Plugs the - * JSTL tlds assuming that they are packaged with the bundle that contains the - * JSTL classes. - *

- * Pluggable tlds at the server level are handled by - * {@link ContainerTldBundleDiscoverer}. - *

- */ -public class JSTLBundleDiscoverer implements TldBundleDiscoverer -{ - private static final Logger LOG = LoggerFactory.getLogger(JSTLBundleDiscoverer.class); - - /** - * Default name of a class that belongs to the jstl bundle. From that class - * we locate the corresponding bundle and register it as a bundle that - * contains tld files. - */ - private static String DEFAULT_JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.el.core.WhenTag"; - - /** - * Default jsp factory implementation. Idally jasper is osgified and we can - * use services. In the mean time we statically set the jsp factory - * implementation. bug #299733 - */ - private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl"; - - private static final Set __tldBundleCache = new HashSet(); - - public JSTLBundleDiscoverer() - { - try - { - // sanity check: - Class cl = getClass().getClassLoader().loadClass("org.apache.jasper.servlet.JspServlet"); - } - catch (Exception e) - { - LOG.warn("Unable to locate the JspServlet: jsp support unavailable.", e); - return; - } - try - { - Class servletContextClass = jakarta.servlet.ServletContext.class; - // bug #299733 - JspFactory fact = JspFactory.getDefaultFactory(); - if (fact == null) - { // bug #299733 - // JspFactory does a simple - // Class.getForName("org.apache.jasper.runtime.JspFactoryImpl") - // however its bundles does not import the jasper package - // so it fails. let's help things out: - fact = (JspFactory)JettyBootstrapActivator.class.getClassLoader() - .loadClass(DEFAULT_JSP_FACTORY_IMPL_CLASS).getDeclaredConstructor().newInstance(); - JspFactory.setDefaultFactory(fact); - } - } - catch (Exception e) - { - LOG.warn("Unable to set the JspFactory: jsp support incomplete.", e); - } - } - - /** - * The jasper TldScanner expects a URLClassloader to parse a jar for the - * /META-INF/*.tld it may contain. We place the bundles that we know contain - * such tag-libraries. Please note that it will work if and only if the - * bundle is a jar (!) Currently we just hardcode the bundle that contains - * the jstl implemenation. - * - * A workaround when the tld cannot be parsed with this method is to copy - * and paste it inside the WEB-INF of the webapplication where it is used. - * - * Support only 2 types of packaging for the bundle: - the bundle is a jar - * (recommended for runtime.) - the bundle is a folder and contain jars in - * the root and/or in the lib folder (nice for PDE development situations) - * Unsupported: the bundle is a jar that embeds more jars. - * - * @return array of URLs - * @throws Exception In case of errors during resolving TLDs files - */ - @Override - public URL[] getUrlsForBundlesWithTlds(DeploymentManager deployer, BundleFileLocatorHelper locatorHelper) throws Exception - { - - ArrayList urls = new ArrayList(); - Class jstlClass = null; - - // Look for the jstl bundle - // We assume the jstl's tlds are defined there. - // We assume that the jstl bundle is imported by this bundle - // So we can look for this class using this bundle's classloader: - try - { - jstlClass = JSTLBundleDiscoverer.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS); - } - catch (ClassNotFoundException e) - { - LOG.info("jstl not on classpath", e); - } - - if (jstlClass != null) - { - //get the bundle containing jstl - Bundle tldBundle = FrameworkUtil.getBundle(jstlClass); - File tldBundleLocation = locatorHelper.getBundleInstallLocation(tldBundle); - - if (tldBundleLocation != null && tldBundleLocation.isDirectory()) - { - // try to find the jar files inside this folder - for (File f : tldBundleLocation.listFiles()) - { - if (FileID.isJavaArchive(f.getName()) && f.isFile()) - { - urls.add(f.toURI().toURL()); - } - else if (f.isDirectory() && f.getName().equals("lib")) - { - for (File f2 : tldBundleLocation.listFiles()) - { - if (FileID.isJavaArchive(f2.getName()) && f2.isFile()) - { - urls.add(f2.toURI().toURL()); - } - } - } - } - } - else if (tldBundleLocation != null) - { - urls.add(tldBundleLocation.toURI().toURL()); - - String pattern = (String)deployer.getContextAttribute("org.eclipse.jetty.server.webapp.containerIncludeBundlePattern"); - pattern = (pattern == null ? "" : pattern); - if (!pattern.contains(tldBundle.getSymbolicName())) - { - pattern += "|" + tldBundle.getSymbolicName(); - deployer.setContextAttribute("org.eclipse.jetty.server.webapp.containerIncludeBundlePattern", pattern); - } - } - } - - return urls.toArray(new URL[urls.size()]); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/FragmentActivator.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/FragmentActivator.java index b795fdc7e76..ee0a386249d 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/FragmentActivator.java +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/FragmentActivator.java @@ -13,8 +13,8 @@ package org.eclipse.jetty.ee10.osgi.boot.jsp; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.jasper.ContainerTldBundleDiscoverer; +import org.eclipse.jetty.ee10.osgi.boot.EE10Activator; +import org.eclipse.jetty.osgi.util.ServerClasspathContributor; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -24,10 +24,9 @@ import org.osgi.framework.BundleContext; * Sets up support for jsp and jstl. All relevant jsp jars must also be installed * into the osgi environment. *

- * Note that as this is part of a bundle fragment, this activator is NOT - * called by the OSGi environment. Instead, the org.eclipse.jetty.ee10.osgi.boot.utils.internal.PackageAdminTracker - * simulates fragment activation and causes this class's start() method to - * be called. + * NOTE that as this is part of a bundle fragment, this activator is NOT + * called by the OSGi environment. Instead, the org.eclipse.jetty.osgi.util.internal.PackageAdminTracker + * simulates fragment activation and causes this class's start() method to be called. *

*

* The package of this class MUST match the Bundle-SymbolicName of this fragment @@ -36,24 +35,21 @@ import org.osgi.framework.BundleContext; */ public class FragmentActivator implements BundleActivator { - /** - * - */ + ServerClasspathContributor _tldClasspathContributor; + @Override public void start(BundleContext context) throws Exception { - //set up some classes that will look for bundles with tlds that must be converted - //to urls and treated as if they are on the Jetty container's classpath so that - //jasper can deal with them - ServerInstanceWrapper.addContainerTldBundleDiscoverer(new ContainerTldBundleDiscoverer()); + //Register a class that will provide the identity of bundles that + //contain TLDs and therefore need to be scanned. + _tldClasspathContributor = new TLDServerClasspathContributor(); + EE10Activator.registerServerClasspathContributor(_tldClasspathContributor); } - /** - * - */ @Override public void stop(BundleContext context) throws Exception { - + EE10Activator.unregisterServerClasspathContributor(_tldClasspathContributor); + _tldClasspathContributor = null; } } diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/TLDServerClasspathContributor.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/TLDServerClasspathContributor.java new file mode 100644 index 00000000000..8f07b1ce8a4 --- /dev/null +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/TLDServerClasspathContributor.java @@ -0,0 +1,112 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.osgi.boot.jsp; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jetty.ee10.osgi.boot.OSGiMetaInfConfiguration; +import org.eclipse.jetty.osgi.util.ServerClasspathContributor; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; + +/** + * @author janb + * + */ +public class TLDServerClasspathContributor implements ServerClasspathContributor +{ + + /** + * Name of a class that belongs to the jstl bundle. From that class + * we locate the corresponding bundle. + */ + private static String JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.el.core.WhenTag"; + + @Override + public List getScannableBundles() + { + if (!isJspAvailable()) + { + return Collections.emptyList(); + } + + List scannableBundles = new ArrayList<>(); + List bundleNames = Collections.emptyList(); + + String tmp = System.getProperty(OSGiMetaInfConfiguration.SYS_PROP_TLD_BUNDLES); //comma separated exact names + + if (tmp != null) + { + String[] names = tmp.split(", \n\r\t"); + bundleNames = Arrays.asList(names); + } + + Bundle jstlBundle = findJstlBundle(); + if (jstlBundle != null) + scannableBundles.add(jstlBundle); + + final Bundle[] bundles = FrameworkUtil.getBundle(getClass()).getBundleContext().getBundles(); + for (Bundle bundle : bundles) + { + if (bundleNames.contains(bundle.getSymbolicName())) + scannableBundles.add(bundle); + } + + return scannableBundles; + } + + /** + * Check that jsp is on the classpath + * + * @return true if jsp is available in the environment + */ + public boolean isJspAvailable() + { + try + { + getClass().getClassLoader().loadClass("org.apache.jasper.servlet.JspServlet"); + return true; + } + catch (Exception e) + { + return false; + } + } + + /** + * Find the bundle that contains a jstl implementation class, which assumes that + * the jstl taglibs will be inside the same bundle. + * + * @return Bundle contains the jstl implementation class + */ + public Bundle findJstlBundle() + { + Class jstlClass = null; + + try + { + jstlClass = getClass().getClassLoader().loadClass(JSTL_BUNDLE_CLASS); + return FrameworkUtil.getBundle(jstlClass); + } + catch (ClassNotFoundException e) + { + //no jstl do nothing + } + + return null; + } +} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty-deploy.xml b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty-deploy.xml index ba8c4da7feb..8cfd3fe6104 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty-deploy.xml +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty-deploy.xml @@ -12,12 +12,6 @@ - diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty.xml b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty.xml index 77a771591f7..0e9be689a0b 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty.xml +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/jettyhome/etc/jetty.xml @@ -37,18 +37,7 @@ - + @@ -75,33 +64,6 @@ - - - - - - org.eclipse.jetty.ee10.webapp.FragmentConfiguration - org.eclipse.jetty.ee10.webapp.JettyWebXmlConfiguration - org.eclipse.jetty.ee10.webapp.WebXmlConfiguration - org.eclipse.jetty.ee10.webapp.WebAppConfiguration - org.eclipse.jetty.ee10.webapp.ServletsConfiguration - org.eclipse.jetty.ee10.webapp.JspConfiguration - org.eclipse.jetty.ee10.webapp.JaasConfiguration - org.eclipse.jetty.ee10.webapp.JndiConfiguration - org.eclipse.jetty.plus.webapp.PlusConfiguration - org.eclipse.jetty.plus.webapp.EnvConfiguration - org.eclipse.jetty.ee10.webapp.JmxConfiguration - org.eclipse.jetty.ee10.osgi.annotations.AnnotationConfiguration - org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration - org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketConfiguration - org.eclipse.jetty.ee10.osgi.boot.OSGiWebInfConfiguration - org.eclipse.jetty.ee10.osgi.boot.OSGiMetaInfConfiguration - - - - - - java.naming.factory.initial diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/pom.xml b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/pom.xml index 9a107f3a46c..51ad5e3600d 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/pom.xml +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/pom.xml @@ -25,7 +25,7 @@ org.eclipse.jetty - jetty-deploy + jetty-osgi ${project.version} @@ -41,9 +41,26 @@ org.eclipse.platform org.eclipse.osgi.services + + org.osgi + org.osgi.service.cm + + + org.osgi + org.osgi.service.event + + + org.osgi + org.osgi.util.tracker + + + + src/main/resources + + maven-antrun-plugin @@ -73,8 +90,8 @@ org.eclipse.jetty.ee10.osgi.boot;singleton:=true - org.eclipse.jetty.ee10.osgi.boot.JettyBootstrapActivator - org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))" + org.eclipse.jetty.ee10.osgi.boot.EE10Activator + org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))", org.eclipse.jetty.ee10.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))" ${osgi.slf4j.import.packages}, jakarta.mail;version="2.0";resolution:=optional, @@ -82,21 +99,22 @@ jakarta.mail.internet;version="2.0";resolution:=optional, jakarta.mail.search;version="2.0";resolution:=optional, jakarta.mail.util;version="2.0";resolution:=optional, - jakarta.servlet;version="[$(version;==;${servletImpl.osgiVersion}),$(version;+;${servletImpl.osgiVersion}))", - jakarta.servlet.http;version="[$(version;==;${servletImpl.osgiVersion}),$(version;+;${servletImpl.osgiVersion}))", + jakarta.servlet;version="[$(version;==;${jakarta.servlet.api.version}),$(version;+;${jakarta.servlet.api.version}))", + jakarta.servlet.http;version="[$(version;==;${jakarta.servlet.api.version}),$(version;+;${jakarta.servlet.api.version}))", jakarta.transaction;version="2.0.0";resolution:=optional, jakarta.transaction.xa;version="2.0.0";resolution:=optional, org.objectweb.asm;version="$(version;=;${asm.version})";resolution:=optional, org.osgi.framework, - org.osgi.service.cm;version="1.4.0", - org.osgi.service.event;version="1.4.0", + org.osgi.service.cm;version="${osgi-service-cm-version}", + org.osgi.service.component;version="${osgi-service-component-version}", + org.osgi.service.event;version="${osgi-service-event-version}", org.osgi.service.packageadmin, org.osgi.service.startlevel;version="1.0.0", org.osgi.service.url;version="1.0.0", - org.osgi.util.tracker;version="1.3.0", + org.osgi.util.tracker;version="${osgi-util-tracker-version}", org.xml.sax, org.xml.sax.helpers, - org.eclipse.jetty.annotations;resolution:=optional, + org.eclipse.jetty.ee10.annotations;resolution:=optional, * diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationConfiguration.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationConfiguration.java index 7ef37bee436..78283ef584a 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationConfiguration.java +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationConfiguration.java @@ -13,19 +13,21 @@ package org.eclipse.jetty.ee10.osgi.annotations; -import java.io.IOException; -import java.net.MalformedURLException; import java.util.HashSet; import java.util.Set; import jakarta.servlet.ServletContainerInitializer; +import org.eclipse.jetty.ee10.annotations.AnnotationConfiguration.ParserTask; +import org.eclipse.jetty.ee10.annotations.AnnotationConfiguration.TimeStatistic; import org.eclipse.jetty.ee10.annotations.AnnotationParser.Handler; import org.eclipse.jetty.ee10.osgi.boot.OSGiMetaInfConfiguration; -import org.eclipse.jetty.ee10.osgi.boot.OSGiWebappConstants; import org.eclipse.jetty.ee10.webapp.Configuration; import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.eclipse.jetty.osgi.OSGiWebappConstants; +import org.eclipse.jetty.util.FileID; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; @@ -80,18 +82,18 @@ public class AnnotationConfiguration extends org.eclipse.jetty.ee10.annotations. * This parser scans the bundles using the OSGi APIs instead of assuming a jar. */ @Override - protected org.eclipse.jetty.ee10.annotations.AnnotationParser createAnnotationParser(int javaTargetVersion) + protected org.eclipse.jetty.ee10.annotations.AnnotationParser createAnnotationParser(int platform) { - return new AnnotationParser(javaTargetVersion); + return new AnnotationParser(platform); } @Override - public Resource getJarFor(ServletContainerInitializer service) throws MalformedURLException, IOException + public Resource getJarFor(ServletContainerInitializer service) { Resource resource = super.getJarFor(service); // TODO This is not correct, but implemented like this to be bug for bug compatible // with previous implementation that could only handle actual jars and not bundles. - if (resource != null && !FileID.isJavaArchive(resource.getFileName())) + if (resource != null && !FileID.isJavaArchive(resource.getURI())) return null; return resource; } @@ -127,7 +129,7 @@ public class AnnotationConfiguration extends org.eclipse.jetty.ee10.annotations. if (bundle.getState() == Bundle.UNINSTALLED) continue; - Resource bundleRes = oparser.indexBundle(bundle); + Resource bundleRes = oparser.indexBundle(ResourceFactory.of(context), bundle); if (!context.getMetaData().getWebInfResources(false).contains(bundleRes)) { context.getMetaData().addWebInfResource(bundleRes); @@ -142,7 +144,7 @@ public class AnnotationConfiguration extends org.eclipse.jetty.ee10.annotations. } } //scan ourselves - oparser.indexBundle(webbundle); + oparser.indexBundle(ResourceFactory.of(context), webbundle); parseWebBundle(context, oparser, webbundle); _webInfLibStats.increment(); diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationParser.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationParser.java index 0c22c65df74..550a5c04afe 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationParser.java +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationParser.java @@ -14,50 +14,54 @@ package org.eclipse.jetty.ee10.osgi.annotations; import java.io.File; -import java.io.InputStream; import java.net.URI; -import java.net.URL; -import java.util.Comparator; -import java.util.Enumeration; import java.util.Set; -import java.util.StringTokenizer; -import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.util.FileID; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.osgi.framework.Bundle; -import org.osgi.framework.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * */ public class AnnotationParser extends org.eclipse.jetty.ee10.annotations.AnnotationParser { - private Set _alreadyParsed = ConcurrentHashMap.newKeySet(); + private static final Logger LOG = LoggerFactory.getLogger(AnnotationParser.class); + + private Set _parsed = ConcurrentHashMap.newKeySet(); private ConcurrentHashMap _uriToBundle = new ConcurrentHashMap<>(); private ConcurrentHashMap _bundleToResource = new ConcurrentHashMap<>(); private ConcurrentHashMap _resourceToBundle = new ConcurrentHashMap<>(); private ConcurrentHashMap _bundleToUri = new ConcurrentHashMap<>(); - public AnnotationParser(int javaPlatform) + public AnnotationParser() { - super(javaPlatform); + super(); + } + + public AnnotationParser(int platform) + { + super(platform); } /** * Keep track of a jetty URI Resource and its associated OSGi bundle. * + *@param resourceFactory the ResourceFactory to convert bundle location * @param bundle the bundle to index * @return the resource for the bundle * @throws Exception if unable to create the resource reference */ - public Resource indexBundle(Bundle bundle) throws Exception + public Resource indexBundle(ResourceFactory resourceFactory, Bundle bundle) throws Exception { File bundleFile = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); - Resource resource = Resource.newResource(bundleFile.toURI()); + Resource resource = resourceFactory.newResource(bundleFile.toURI()); URI uri = resource.getURI(); _uriToBundle.putIfAbsent(uri, bundle); _bundleToUri.putIfAbsent(bundle, uri); @@ -81,145 +85,57 @@ public class AnnotationParser extends org.eclipse.jetty.ee10.annotations.Annotat return _resourceToBundle.get(resource); } - /** - * - */ - @Override - public void parse(Set handlers, URI[] uris) - throws Exception - { - for (URI uri : uris) - { - Bundle associatedBundle = _uriToBundle.get(uri); - if (associatedBundle == null) - { - if (!_alreadyParsed.add(uri)) - { - continue; - } - //a jar in WEB-INF/lib or the WEB-INF/classes - //use the behavior of the super class for a standard jar. - super.parse(handlers, new URI[]{uri}); - } - else - { - parse(handlers, associatedBundle); - } - } - } - public void parse(Set handlers, Bundle bundle) throws Exception { - URI uri = _bundleToUri.get(bundle); - if (!_alreadyParsed.add(uri)) + + Resource bundleResource = _bundleToResource.get(bundle); + if (bundleResource == null) + return; + + //if already added, it is already parsed + if (!_parsed.add(_bundleToUri.get(bundle))) + return; + + parse(handlers, bundleResource); + } + + @Override + public void parse(final Set handlers, Resource r) throws Exception + { + if (r == null) + return; + + if (!r.exists()) + return; + + if (FileID.isJavaArchive(r.getPath())) { + parseJar(handlers, r); return; } - String bundleClasspath = (String)bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH); - if (bundleClasspath == null) - { - bundleClasspath = "."; - } - //order the paths first by the number of tokens in the path second alphabetically. - TreeSet paths = new TreeSet<>( - new Comparator() - { - @Override - public int compare(String o1, String o2) - { - int paths1 = new StringTokenizer(o1, "/", false).countTokens(); - int paths2 = new StringTokenizer(o2, "/", false).countTokens(); - if (paths1 == paths2) - { - return o1.compareTo(o2); - } - return paths2 - paths1; - } - }); - boolean hasDotPath = false; - StringTokenizer tokenizer = new StringTokenizer(bundleClasspath, StringUtil.DEFAULT_DELIMS, false); - while (tokenizer.hasMoreTokens()) - { - String token = tokenizer.nextToken().trim(); - if (!token.startsWith("/")) - { - token = "/" + token; - } - if (token.equals("/.")) - { - hasDotPath = true; - } - else if (!FileID.isJavaArchive(token) && !token.endsWith("/")) - { - paths.add(token + "/"); - } - else - { - paths.add(token); - } - } - //support the development environment: maybe the classes are inside bin or target/classes - //this is certainly not useful in production. - //however it makes our life so much easier during development. - if (bundle.getEntry("/.classpath") != null) - { - if (bundle.getEntry("/bin/") != null) - { - paths.add("/bin/"); - } - else if (bundle.getEntry("/target/classes/") != null) - { - paths.add("/target/classes/"); - } - } - @SuppressWarnings("rawtypes") - Enumeration classes = bundle.findEntries("/", "*.class", true); - if (classes == null) + if (r.isDirectory()) { + parseDir(handlers, r); return; } - while (classes.hasMoreElements()) + + if (FileID.isClassFile(r.getPath())) { - URL classUrl = (URL)classes.nextElement(); - String path = classUrl.getPath(); - //remove the longest path possible: - String name = null; - for (String prefixPath : paths) - { - if (path.startsWith(prefixPath)) - { - name = path.substring(prefixPath.length()); - break; - } - } - if (name == null && hasDotPath) - { - //remove the starting '/' - name = path.substring(1); - } - if (name == null) - { - //found some .class file in the archive that was not under one of the prefix paths - //or the bundle classpath wasn't simply ".", so skip it - continue; - } + parseClass(handlers, null, r.getPath()); + } - if (!isValidClassFileName(name)) - { - continue; //eg skip module-info.class - } - - //transform into a classname to pass to the resolver - String shortName = StringUtil.replace(name, '/', '.').substring(0, name.length() - 6); - - addParsedClass(shortName, getResource(bundle)); - - try (InputStream classInputStream = classUrl.openStream()) - { - scanClass(handlers, getResource(bundle), classInputStream); - } + //Not already parsed, it could be a file that actually is compressed but does not have + //.jar/.zip etc extension, such as equinox urls, so try to parse it + try + { + parseJar(handlers, r); + } + catch (Exception e) + { + if (LOG.isDebugEnabled()) + LOG.warn("Resource not able to be scanned for classes: {}", r); } } } diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractContextProvider.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractContextProvider.java deleted file mode 100644 index 9b8e98058c6..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractContextProvider.java +++ /dev/null @@ -1,235 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import java.io.File; -import java.util.Dictionary; -import java.util.HashMap; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee10.osgi.boot.utils.OSGiClassLoader; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.resource.JarResource; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.osgi.framework.Bundle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractContextProvider - * - * Base class for DeploymentManager Providers that can deploy ContextHandlers into - * Jetty that have been discovered via OSGI either as bundles or services. - */ -public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); - - private DeploymentManager _deploymentManager; - - private ServerInstanceWrapper _serverWrapper; - - /** - * OSGiApp - */ - public class OSGiApp extends AbstractOSGiApp - { - private String _contextFile; - private ContextHandler _contextHandler; - private boolean _configured = false; - - public OSGiApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile) - { - super(manager, provider, bundle, originId); - _contextFile = contextFile; - } - - public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String contextFile, String originId) - { - super(manager, provider, bundle, properties, originId); - _contextFile = contextFile; - } - - public String getContextFile() - { - return _contextFile; - } - - public void setHandler(ContextHandler h) - { - _contextHandler = h; - } - - public ContextHandler createContextHandler() - throws Exception - { - configureContextHandler(); - return _contextHandler; - } - - public void configureContextHandler() - throws Exception - { - if (_configured) - return; - - _configured = true; - - //Override for bundle root may have been set - String bundleOverrideLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); - - //Location on filesystem of bundle or the bundle override location - File bundleLocation = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle); - File root = (bundleOverrideLocation == null ? bundleLocation : new File(bundleOverrideLocation)); - Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(root.toURI().toURL())); - - //try and make sure the rootResource is useable - if its a jar then make it a jar file url - if (rootResource.exists() && !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:")) - { - Resource jarResource = JarResource.newJarResource(rootResource); - if (jarResource.exists() && jarResource.isDirectory()) - rootResource = jarResource; - } - - //Set the base resource of the ContextHandler, if not already set, can also be overridden by the context xml file - if (_contextHandler != null && _contextHandler.getResourceBase() == null) - { - _contextHandler.setResourceBase(rootResource.getPath()); - } - - //Use a classloader that knows about the common jetty parent loader, and also the bundle - OSGiClassLoader classLoader = new OSGiClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps(), _bundle); - - //if there is a context file, find it and apply it - if (_contextFile == null && _contextHandler == null) - throw new IllegalStateException("No context file or ContextHandler"); - - if (_contextFile != null) - { - //apply the contextFile, creating the ContextHandler, the DeploymentManager will register it in the ContextHandlerCollection - Resource res = null; - - String jettyHome = (String)getServerInstanceWrapper().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); - if (jettyHome == null) - jettyHome = System.getProperty(OSGiServerConstants.JETTY_HOME); - - res = findFile(_contextFile, jettyHome, bundleOverrideLocation, _bundle); - - //apply the context xml file, either to an existing ContextHandler, or letting the - //it create the ContextHandler as necessary - if (res != null) - { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - - if (LOG.isDebugEnabled()) - LOG.debug("Context classloader = {}", cl); - try - { - Thread.currentThread().setContextClassLoader(classLoader); - - XmlConfiguration xmlConfiguration = new XmlConfiguration(res); - HashMap properties = new HashMap(); - //put the server instance in - properties.put("Server", getServerInstanceWrapper().getServer()); - //put in the location of the bundle root - properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString()); - - // insert the bundle's location as a property. - xmlConfiguration.getProperties().putAll(properties); - - if (_contextHandler == null) - _contextHandler = (ContextHandler)xmlConfiguration.configure(); - else - xmlConfiguration.configure(_contextHandler); - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - } - - //Set up the class loader we created - _contextHandler.setClassLoader(classLoader); - - //If a bundle/service property specifies context path, let it override the context xml - String contextPath = (String)_properties.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - if (contextPath != null) - _contextHandler.setContextPath(contextPath); - - //osgi Enterprise Spec r4 p.427 - _contextHandler.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, _bundle.getBundleContext()); - - //make sure we protect also the osgi dirs specified by OSGi Enterprise spec - - if (_contextHandler instanceof ServletContextHandler servletContextHandler) - { - String[] targets = servletContextHandler.getProtectedTargets(); - int length = (targets == null ? 0 : targets.length); - - String[] updatedTargets = null; - if (targets != null) - { - updatedTargets = new String[length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(targets, 0, updatedTargets, 0, length); - } - else - updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); - servletContextHandler.setProtectedTargets(updatedTargets); - } - } - } - - public AbstractContextProvider(ServerInstanceWrapper wrapper) - { - _serverWrapper = wrapper; - } - - public ServerInstanceWrapper getServerInstanceWrapper() - { - return _serverWrapper; - } - - @Override - public ContextHandler createContextHandler(App app) throws Exception - { - if (app == null) - return null; - if (!(app instanceof OSGiApp)) - throw new IllegalStateException(app + " is not a BundleApp"); - - //Create a ContextHandler suitable to deploy in OSGi - ContextHandler h = ((OSGiApp)app).createContextHandler(); - return h; - } - - @Override - public void setDeploymentManager(DeploymentManager deploymentManager) - { - _deploymentManager = deploymentManager; - } - - public DeploymentManager getDeploymentManager() - { - return _deploymentManager; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractOSGiApp.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractOSGiApp.java deleted file mode 100644 index 9d95c013ecd..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractOSGiApp.java +++ /dev/null @@ -1,195 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import java.io.File; -import java.net.URL; -import java.util.Dictionary; -import java.util.Hashtable; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.resource.Resource; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceRegistration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractOSGiApp - * - * Base class representing info about a webapp/ContextHandler that is deployed into Jetty. - */ -public abstract class AbstractOSGiApp extends App -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractOSGiApp.class); - - protected Bundle _bundle; - protected Dictionary _properties; - protected ServiceRegistration _registration; - - public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId) - { - this(manager, provider, bundle, bundle.getHeaders(), originId); - } - - public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId) - { - super(manager, provider, null, originId); // TODO environment - _properties = properties; - _bundle = bundle; - } - - public String getBundleSymbolicName() - { - return _bundle.getSymbolicName(); - } - - public String getBundleVersionAsString() - { - if (_bundle.getVersion() == null) - return null; - return _bundle.getVersion().toString(); - } - - public Bundle getBundle() - { - return _bundle; - } - - public void setRegistration(ServiceRegistration registration) - { - _registration = registration; - } - - public ServiceRegistration getRegistration() - { - return _registration; - } - - public void registerAsOSGiService() throws Exception - { - if (_registration == null) - { - Dictionary properties = new Hashtable(); - properties.put(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK); - if (getBundleSymbolicName() != null) - properties.put(OSGiWebappConstants.OSGI_WEB_SYMBOLICNAME, getBundleSymbolicName()); - if (getBundleVersionAsString() != null) - properties.put(OSGiWebappConstants.OSGI_WEB_VERSION, getBundleVersionAsString()); - properties.put(OSGiWebappConstants.OSGI_WEB_CONTEXTPATH, getContextPath()); - ServiceRegistration rego = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ContextHandler.class.getName(), getContextHandler(), properties); - setRegistration(rego); - } - } - - protected void deregisterAsOSGiService() throws Exception - { - if (_registration == null) - return; - - _registration.unregister(); - _registration = null; - } - - protected Resource getFileAsResource(String dir, String file) - { - Resource r = null; - try - { - File asFile = new File(dir, file); - if (asFile.exists()) - r = Resource.newResource(asFile); - } - catch (Exception e) - { - r = null; - } - return r; - } - - protected Resource getFileAsResource(String file) - { - Resource r = null; - try - { - File asFile = new File(file); - if (asFile.exists()) - r = Resource.newResource(asFile); - } - catch (Exception e) - { - r = null; - } - return r; - } - - protected Resource findFile(String fileName, String jettyHome, String bundleOverrideLocation, Bundle containingBundle) - { - Resource res = null; - - //try to find the context file in the filesystem - if (fileName.startsWith("/")) - res = getFileAsResource(fileName); - if (res != null) - return res; - - //try to find it relative to jetty home - if (jettyHome != null) - { - if (jettyHome.startsWith("\"") || jettyHome.startsWith("'")) - jettyHome = jettyHome.substring(1); - if (jettyHome.endsWith("\"") || (jettyHome.endsWith("'"))) - jettyHome = jettyHome.substring(0, jettyHome.length() - 1); - - res = getFileAsResource(jettyHome, fileName); - } - if (res != null) - return res; - - //try to find it relative to an override location that has been specified - if (bundleOverrideLocation != null) - { - try (Resource location = Resource.newResource(bundleOverrideLocation)) - { - res = location.addPath(fileName); - } - catch (Exception e) - { - LOG.warn("Unable to find relative override location: {}", bundleOverrideLocation, e); - } - } - if (res != null) - return res; - - //try to find it relative to the bundle in which it is being deployed - if (containingBundle != null) - { - if (fileName.startsWith("./")) - fileName = fileName.substring(1); - - if (!fileName.startsWith("/")) - fileName = "/" + fileName; - - URL entry = _bundle.getEntry(fileName); - if (entry != null) - res = Resource.newResource(entry); - } - - return res; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractWebAppProvider.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractWebAppProvider.java deleted file mode 100644 index 0d4f714d27a..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/AbstractWebAppProvider.java +++ /dev/null @@ -1,553 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import java.io.File; -import java.net.URI; -import java.net.URL; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.HashMap; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.internal.webapp.OSGiWebappClassLoader; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee10.webapp.WebAppClassLoader; -import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.resource.JarResource; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.service.packageadmin.PackageAdmin; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractWebAppProvider - *

- * Base class for Jetty DeploymentManager Providers that are capable of deploying a webapp, - * either from a bundle or an OSGi service. - */ -public abstract class AbstractWebAppProvider extends AbstractLifeCycle implements AppProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); - - private boolean _parentLoaderPriority; - - private String _defaultsDescriptor; - - private boolean _extractWars = true; //See WebAppContext.extractWars - - private String _tldBundles; - - private DeploymentManager _deploymentManager; - - private ServerInstanceWrapper _serverWrapper; - - /** - * OSGiApp - * - * Represents a deployable webapp. - */ - public class OSGiApp extends AbstractOSGiApp - { - private String _contextPath; - private String _webAppPath; - private WebAppContext _webApp; - - public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId) - { - super(manager, provider, bundle, originId); - } - - public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId) - { - super(manager, provider, bundle, properties, originId); - } - - public void setWebAppContext(WebAppContext webApp) - { - _webApp = webApp; - } - - @Override - public String getContextPath() - { - return _contextPath; - } - - public void setContextPath(String contextPath) - { - this._contextPath = contextPath; - } - - public String getBundlePath() - { - return _webAppPath; - } - - public void setWebAppPath(String path) - { - this._webAppPath = path; - } - - public ContextHandler createContextHandler() - throws Exception - { - if (_webApp != null) - { - configureWebApp(); - return _webApp; - } - - createWebApp(); - return _webApp; - } - - protected void createWebApp() - throws Exception - { - _webApp = newWebApp(); - configureWebApp(); - } - - protected WebAppContext newWebApp() - { - WebAppContext webApp = new WebAppContext(); - webApp.setAttribute(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK); - - //make sure we protect also the osgi dirs specified by OSGi Enterprise spec - String[] targets = webApp.getProtectedTargets(); - String[] updatedTargets = null; - if (targets != null) - { - updatedTargets = new String[targets.length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(targets, 0, updatedTargets, 0, targets.length); - } - else - updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, targets.length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); - webApp.setProtectedTargets(updatedTargets); - - return webApp; - } - - public void configureWebApp() - throws Exception - { - //TODO turn this around and let any context.xml file get applied first, and have the properties override - _webApp.setContextPath(_contextPath); - - //osgi Enterprise Spec r4 p.427 - _webApp.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, _bundle.getBundleContext()); - - String overrideBundleInstallLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); - File bundleInstallLocation = - (overrideBundleInstallLocation == null - ? BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle) - : new File(overrideBundleInstallLocation)); - - if (LOG.isDebugEnabled()) - { - LOG.debug("Bundle location is {}, install location: {}", _bundle.getLocation(), bundleInstallLocation); - } - - URL url = null; - Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(bundleInstallLocation.toURI().toURL())); - //try and make sure the rootResource is useable - if its a jar then make it a jar file url - if (rootResource.exists() && !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:")) - { - Resource jarResource = JarResource.newJarResource(rootResource); - if (jarResource.exists() && jarResource.isDirectory()) - rootResource = jarResource; - } - - //if the path wasn't set or it was ., then it is the root of the bundle's installed location - if (_webAppPath == null || _webAppPath.length() == 0 || ".".equals(_webAppPath)) - { - url = bundleInstallLocation.toURI().toURL(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using bundle install location: {}", url); - } - else - { - //Get the location of the root of the webapp inside the installed bundle - if (_webAppPath.startsWith("/") || _webAppPath.startsWith("file:")) - { - url = new File(_webAppPath).toURI().toURL(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using absolute location: {}", url); - } - else if (bundleInstallLocation != null && bundleInstallLocation.isDirectory()) - { - url = new File(bundleInstallLocation, _webAppPath).toURI().toURL(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using path relative to bundle unpacked install location: {}", url); - } - else if (bundleInstallLocation != null) - { - Enumeration urls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(_bundle, _webAppPath); - if (urls != null && urls.hasMoreElements()) - { - url = urls.nextElement(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using path relative to packed bundle location: {}", url); - } - } - } - - if (url == null) - { - throw new IllegalArgumentException("Unable to locate " + _webAppPath + " in " + - (bundleInstallLocation != null ? bundleInstallLocation.getAbsolutePath() : "unlocated bundle '" + _bundle.getSymbolicName() + "'")); - } - - //Sets the location of the war file - // converts bundleentry: protocol if necessary - _webApp.setWar(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(url).toString()); - - // Set up what has been configured on the provider - _webApp.setParentLoaderPriority(isParentLoaderPriority()); - _webApp.setExtractWAR(isExtract()); - - //Set up configuration from manifest headers - //extra classpath - String tmp = (String)_properties.get(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH); - if (tmp != null) - _webApp.setExtraClasspath(tmp); - - //web.xml - tmp = (String)_properties.get(OSGiWebappConstants.JETTY_WEB_XML_PATH); - if (tmp != null && tmp.trim().length() != 0) - { - File webXml = getFile(tmp, bundleInstallLocation); - if (webXml != null && webXml.exists()) - _webApp.setDescriptor(webXml.getAbsolutePath()); - } - - //webdefault-ee10.xml - tmp = (String)_properties.get(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH); - if (tmp != null) - { - File defaultWebXml = getFile(tmp, bundleInstallLocation); - if (defaultWebXml != null) - { - if (defaultWebXml.exists()) - _webApp.setDefaultsDescriptor(defaultWebXml.getAbsolutePath()); - else - LOG.warn("{} does not exist", defaultWebXml.getAbsolutePath()); - } - } - - //Handle Require-TldBundle - //This is a comma separated list of names of bundles that contain tlds that this webapp uses. - //We add them to the webapp classloader. - String requireTldBundles = (String)_properties.get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); - String pathsToTldBundles = getPathsToRequiredBundles(requireTldBundles); - - // make sure we provide access to all the jetty bundles by going - // through this bundle. - OSGiWebappClassLoader webAppLoader = new OSGiWebappClassLoader(_serverWrapper.getParentClassLoaderForWebapps(), _webApp, _bundle); - - if (pathsToTldBundles != null) - webAppLoader.addClassPath(pathsToTldBundles); - _webApp.setClassLoader(webAppLoader); - - // apply any META-INF/context.xml file that is found to configure - // the webapp first - try - { - final Resource finalRootResource = rootResource; - WebAppClassLoader.runWithServerClassAccess(() -> - { - applyMetaInfContextXml(finalRootResource, overrideBundleInstallLocation); - return null; - }); - } - catch (Exception e) - { - LOG.warn("Error applying context xml"); - throw e; - } - - _webApp.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundles); - - //Set up some attributes - // rfc66 - _webApp.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT, _bundle.getBundleContext()); - - // spring-dm-1.2.1 looks for the BundleContext as a different attribute. - // not a spec... but if we want to support - // org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext - // then we need to do this to: - _webApp.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), _bundle.getBundleContext()); - - // also pass the bundle directly. sometimes a bundle does not have a - // bundlecontext. - // it is still useful to have access to the Bundle from the servlet - // context. - _webApp.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, _bundle); - } - - protected String getPathsToRequiredBundles(String requireTldBundles) - throws Exception - { - if (requireTldBundles == null) - return null; - - ServiceReference ref = _bundle.getBundleContext().getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName()); - PackageAdmin packageAdmin = (ref == null) ? null : (PackageAdmin)_bundle.getBundleContext().getService(ref); - if (packageAdmin == null) - throw new IllegalStateException("Unable to get PackageAdmin reference to locate required Tld bundles"); - - StringBuilder paths = new StringBuilder(); - String[] symbNames = requireTldBundles.split("[, ]"); - - for (String symbName : symbNames) - { - Bundle[] bs = packageAdmin.getBundles(symbName, null); - if (bs == null || bs.length == 0) - { - throw new IllegalArgumentException("Unable to locate the bundle '" + symbName + "' specified by " + - OSGiWebappConstants.REQUIRE_TLD_BUNDLE + " in manifest of " + - (_bundle == null ? "unknown" : _bundle.getSymbolicName())); - } - - File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bs[0]); - if (paths.length() > 0) - paths.append(", "); - paths.append(f.toURI().toURL().toString()); - if (LOG.isDebugEnabled()) - LOG.debug("getPathsToRequiredBundles: bundle path={} uri={}", bs[0].getLocation(), f.toURI()); - } - - return paths.toString(); - } - - protected void applyMetaInfContextXml(Resource rootResource, String overrideBundleInstallLocation) - throws Exception - { - if (_bundle == null) - return; - if (_webApp == null) - return; - - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (LOG.isDebugEnabled()) - LOG.debug("Context classloader = {}", cl); - try - { - - Thread.currentThread().setContextClassLoader(_webApp.getClassLoader()); - - URI contextXmlUri = null; - - //TODO replace this with getting the InputStream so we don't cache in URL - //Try looking for a context xml file in META-INF with a specific name - URL url = _bundle.getEntry("/META-INF/jetty-webapp-context.xml"); - if (url != null) - { - contextXmlUri = url.toURI(); - } - - if (contextXmlUri == null) - { - //Didn't find specially named file, try looking for a property that names a context xml file to use - if (_properties != null) - { - String tmp = (String)_properties.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); - if (tmp != null) - { - String[] filenames = tmp.split("[,;]"); - if (filenames != null && filenames.length > 0) - { - String filename = filenames[0]; //should only be 1 filename in this usage - String jettyHome = (String)getServerInstanceWrapper().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); - if (jettyHome == null) - jettyHome = System.getProperty(OSGiServerConstants.JETTY_HOME); - Resource res = findFile(filename, jettyHome, overrideBundleInstallLocation, _bundle); - if (res != null) - { - contextXmlUri = res.getURI(); - } - } - } - } - } - if (contextXmlUri == null) - return; - - // Apply it just as the standard jetty ContextProvider would do - LOG.info("Applying {} to {}", contextXmlUri, _webApp); - - XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.newResource(contextXmlUri)); - WebAppClassLoader.runWithServerClassAccess(() -> - { - HashMap properties = new HashMap<>(); - xmlConfiguration.getIdMap().put("Server", getDeploymentManager().getServer()); - properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString()); - properties.put(OSGiServerConstants.JETTY_HOME, (String)getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME)); - xmlConfiguration.getProperties().putAll(properties); - xmlConfiguration.configure(_webApp); - return null; - }); - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - - private File getFile(String file, File bundleInstall) - { - if (file == null) - return null; - - if (file.startsWith("/") || file.startsWith("file:/")) //absolute location - return new File(file); - else - { - //relative location - //try inside the bundle first - File f = new File(bundleInstall, file); - if (f.exists()) - return f; - String jettyHome = (String)getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); - if (jettyHome != null) - return new File(jettyHome, file); - } - - return null; - } - } - - public AbstractWebAppProvider(ServerInstanceWrapper wrapper) - { - _serverWrapper = wrapper; - } - - /** - * Get the parentLoaderPriority. - * - * @return the parentLoaderPriority - */ - public boolean isParentLoaderPriority() - { - return _parentLoaderPriority; - } - - /** - * Set the parentLoaderPriority. - * - * @param parentLoaderPriority the parentLoaderPriority to set - */ - public void setParentLoaderPriority(boolean parentLoaderPriority) - { - _parentLoaderPriority = parentLoaderPriority; - } - - /** - * Get the defaultsDescriptor. - * - * @return the defaultsDescriptor - */ - public String getDefaultsDescriptor() - { - return _defaultsDescriptor; - } - - /** - * Set the defaultsDescriptor. - * - * @param defaultsDescriptor the defaultsDescriptor to set - */ - public void setDefaultsDescriptor(String defaultsDescriptor) - { - _defaultsDescriptor = defaultsDescriptor; - } - - public boolean isExtract() - { - return _extractWars; - } - - public void setExtract(boolean extract) - { - _extractWars = extract; - } - - /** - * @param tldBundles Comma separated list of bundles that contain tld jars - * that should be setup on the jetty instances created here. - */ - public void setTldBundles(String tldBundles) - { - _tldBundles = tldBundles; - } - - /** - * @return The list of bundles that contain tld jars that should be setup on - * the jetty instances created here. - */ - public String getTldBundles() - { - return _tldBundles; - } - - public void setServerInstanceWrapper(ServerInstanceWrapper wrapper) - { - _serverWrapper = wrapper; - } - - public ServerInstanceWrapper getServerInstanceWrapper() - { - return _serverWrapper; - } - - public DeploymentManager getDeploymentManager() - { - return _deploymentManager; - } - - @Override - public void setDeploymentManager(DeploymentManager deploymentManager) - { - _deploymentManager = deploymentManager; - } - - @Override - public ContextHandler createContextHandler(App app) throws Exception - { - if (app == null) - return null; - if (!(app instanceof OSGiApp)) - throw new IllegalStateException(app + " is not a BundleApp"); - - //Create a WebAppContext suitable to deploy in OSGi - ContextHandler ch = ((OSGiApp)app).createContextHandler(); - return ch; - } - - public static String getOriginId(Bundle contributor, String path) - { - return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() + (path.startsWith("/") ? path : "/" + path); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleWebAppProvider.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleWebAppProvider.java deleted file mode 100644 index 2f223c22879..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/BundleWebAppProvider.java +++ /dev/null @@ -1,257 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.utils.Util; -import org.eclipse.jetty.util.StringUtil; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleEvent; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.BundleTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * BundleWebAppProvider - *

- * A Jetty Provider that knows how to deploy a WebApp contained inside a Bundle. - */ -public class BundleWebAppProvider extends AbstractWebAppProvider implements BundleProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); - - /** - * Map of Bundle to App. Used when a Bundle contains a webapp. - */ - private Map _bundleMap = new HashMap<>(); - - private ServiceRegistration _serviceRegForBundles; - - private WebAppTracker _webappTracker; - - public class WebAppTracker extends BundleTracker - { - protected String _managedServerName; - - public WebAppTracker(BundleContext bundleContext, String managedServerName) - { - super(bundleContext, Bundle.ACTIVE | Bundle.STOPPING, null); - _managedServerName = managedServerName; - } - - @Override - public Object addingBundle(Bundle bundle, BundleEvent event) - { - try - { - String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME)) || - (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName)))) - { - if (bundleAdded(bundle)) - return bundle; - } - } - catch (Exception e) - { - LOG.warn("Unable to add bundle {}", bundle, e); - } - return null; - } - - @Override - public void removedBundle(Bundle bundle, BundleEvent event, Object object) - { - try - { - bundleRemoved(bundle); - } - catch (Exception e) - { - LOG.warn("Unable to remove bundle {}", bundle, e); - } - } - } - - public BundleWebAppProvider(ServerInstanceWrapper wrapper) - { - super(wrapper); - } - - @Override - protected void doStart() throws Exception - { - _webappTracker = new WebAppTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName()); - _webappTracker.open(); - //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to - Dictionary properties = new Hashtable<>(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); - _serviceRegForBundles = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(BundleProvider.class.getName(), this, properties); - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - _webappTracker.close(); - - //unregister ourselves - if (_serviceRegForBundles != null) - { - try - { - _serviceRegForBundles.unregister(); - } - catch (Exception e) - { - LOG.warn("Unable to unregister {}", _serviceRegForBundles, e); - } - } - - super.doStop(); - } - - /** - * A bundle has been added that could be a webapp - * - * @param bundle the bundle - */ - @Override - public boolean bundleAdded(Bundle bundle) throws Exception - { - if (bundle == null) - return false; - - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps()); - String contextPath = null; - try - { - @SuppressWarnings("unchecked") - Dictionary headers = bundle.getHeaders(); - - //does the bundle have a OSGiWebappConstants.JETTY_WAR_FOLDER_PATH - String resourcePath = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, headers); - if (resourcePath != null) - { - String base = resourcePath; - contextPath = getContextPath(bundle); - String originId = getOriginId(bundle, base); - - //TODO : we don't know whether an app is actually deployed, as deploymentManager swallows all - //exceptions inside the impl of addApp. Need to send the Event and also register as a service - //only if the deployment succeeded - OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId); - app.setWebAppPath(base); - app.setContextPath(contextPath); - _bundleMap.put(bundle, app); - getDeploymentManager().addApp(app); - return true; - } - - //does the bundle have a WEB-INF/web.xml - if (bundle.getEntry("/WEB-INF/web.xml") != null) - { - String base = "."; - contextPath = getContextPath(bundle); - String originId = getOriginId(bundle, base); - - OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId); - app.setContextPath(contextPath); - app.setWebAppPath(base); - _bundleMap.put(bundle, app); - getDeploymentManager().addApp(app); - return true; - } - - //does the bundle define a OSGiWebappConstants.RFC66_WEB_CONTEXTPATH - if (headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) != null) - { - //Could be a static webapp with no web.xml - String base = "."; - contextPath = headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - String originId = getOriginId(bundle, base); - - OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId); - app.setContextPath(contextPath); - app.setWebAppPath(base); - _bundleMap.put(bundle, app); - getDeploymentManager().addApp(app); - return true; - } - - return false; - } - catch (Exception e) - { - - throw e; - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - - /** - * Bundle has been removed. If it was a webapp we deployed, undeploy it. - * - * @param bundle the bundle - * @return true if this was a webapp we had deployed, false otherwise - */ - @Override - public boolean bundleRemoved(Bundle bundle) throws Exception - { - App app = _bundleMap.remove(bundle); - if (app != null) - { - getDeploymentManager().removeApp(app); - return true; - } - return false; - } - - private static String getContextPath(Bundle bundle) - { - Dictionary headers = bundle.getHeaders(); - String contextPath = (String)headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - if (contextPath == null) - { - // extract from the last token of the bundle's location: - // (really ?could consider processing the symbolic name as an alternative - // the location will often reflect the version. - // maybe this is relevant when the file is a war) - String location = bundle.getLocation(); - String[] toks = StringUtil.replace(location, '\\', '/').split("/"); - contextPath = toks[toks.length - 1]; - // remove .jar, .war etc: - int lastDot = contextPath.lastIndexOf('.'); - if (lastDot != -1) - contextPath = contextPath.substring(0, lastDot); - } - if (!contextPath.startsWith("/")) - contextPath = "/" + contextPath; - - return contextPath; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/EE10Activator.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/EE10Activator.java new file mode 100644 index 00000000000..32a4ffd5bd2 --- /dev/null +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/EE10Activator.java @@ -0,0 +1,613 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.osgi.boot; + +import java.io.File; +import java.net.URI; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.eclipse.jetty.deploy.App; +import org.eclipse.jetty.deploy.AppProvider; +import org.eclipse.jetty.deploy.DeploymentManager; +import org.eclipse.jetty.ee10.webapp.Configuration; +import org.eclipse.jetty.ee10.webapp.Configurations; +import org.eclipse.jetty.ee10.webapp.WebAppClassLoader; +import org.eclipse.jetty.ee10.webapp.WebAppContext; +import org.eclipse.jetty.osgi.AbstractContextProvider; +import org.eclipse.jetty.osgi.BundleContextProvider; +import org.eclipse.jetty.osgi.BundleWebAppProvider; +import org.eclipse.jetty.osgi.ContextFactory; +import org.eclipse.jetty.osgi.OSGiApp; +import org.eclipse.jetty.osgi.OSGiServerConstants; +import org.eclipse.jetty.osgi.OSGiWebappConstants; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.FakeURLClassLoader; +import org.eclipse.jetty.osgi.util.OSGiClassLoader; +import org.eclipse.jetty.osgi.util.ServerClasspathContributor; +import org.eclipse.jetty.osgi.util.Util; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.FileID; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.eclipse.jetty.util.resource.URLResourceFactory; +import org.eclipse.jetty.xml.XmlConfiguration; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * EE10Activator + *

+ * Enable deployment of webapps/contexts to E10E + */ +public class EE10Activator implements BundleActivator +{ + private static final Logger LOG = LoggerFactory.getLogger(EE10Activator.class); + + public static final String ENVIRONMENT = "ee10"; + + private static Collection __serverClasspathContributors = new ArrayList<>(); + + public static void registerServerClasspathContributor(ServerClasspathContributor contributor) + { + __serverClasspathContributors.add(contributor); + } + + public static void unregisterServerClasspathContributor(ServerClasspathContributor contributor) + { + __serverClasspathContributors.remove(contributor); + } + + public static Collection getServerClasspathContributors() + { + return __serverClasspathContributors; + } + + /** + * ServerTracker + * + * Tracks appearance of Server instances as OSGi services, and then configures them + * for deployment of EE10 contexts and webapps. + * + */ + public static class ServerTracker implements ServiceTrackerCustomizer + { + private Bundle _myBundle = null; + + public ServerTracker(Bundle bundle) + { + _myBundle = bundle; + } + + @Override + public Object addingService(ServiceReference sr) + { + Bundle contributor = sr.getBundle(); + Server server = contributor.getBundleContext().getService(sr); + //find bundles that should be on the container classpath and convert to URLs + List contributedURLs = new ArrayList<>(); + List contributedBundles = new ArrayList<>(); + Collection serverClasspathContributors = getServerClasspathContributors(); + serverClasspathContributors.stream().forEach(c -> contributedBundles.addAll(c.getScannableBundles())); + contributedBundles.stream().forEach(b -> contributedURLs.addAll(convertBundleToURL(b))); + + if (!contributedURLs.isEmpty()) + { + //There should already be a default set up by the JettyServerFactory + ClassLoader serverClassLoader = (ClassLoader)server.getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + if (serverClassLoader != null) + { + server.setAttribute(OSGiServerConstants.SERVER_CLASSLOADER, + new FakeURLClassLoader(serverClassLoader, contributedURLs.toArray(new URL[contributedURLs.size()]))); + + if (LOG.isDebugEnabled()) + LOG.debug("Server classloader for contexts = {}", server.getAttribute(OSGiServerConstants.SERVER_CLASSLOADER)); + } + server.setAttribute(OSGiServerConstants.SERVER_CLASSPATH_BUNDLES, contributedBundles); + } + + Optional deployer = getDeploymentManager(server); + BundleWebAppProvider webAppProvider = null; + BundleContextProvider contextProvider = null; + + String containerScanBundlePattern = null; + if (contributedBundles != null) + { + StringBuffer strbuff = new StringBuffer(); + contributedBundles.stream().forEach(b -> strbuff.append(b.getSymbolicName()).append("|")); + + if (strbuff.length() > 0) + containerScanBundlePattern = strbuff.toString().substring(0, strbuff.length() - 1); + } + + if (deployer.isPresent()) + { + for (AppProvider provider : deployer.get().getAppProviders()) + { + if (BundleContextProvider.class.isInstance(provider) && ENVIRONMENT.equalsIgnoreCase(provider.getEnvironmentName())) + contextProvider = BundleContextProvider.class.cast(provider); + if (BundleWebAppProvider.class.isInstance(provider) && ENVIRONMENT.equalsIgnoreCase(provider.getEnvironmentName())) + webAppProvider = BundleWebAppProvider.class.cast(provider); + } + if (contextProvider == null) + { + contextProvider = new BundleContextProvider(ENVIRONMENT, server, new EE10ContextFactory(_myBundle)); + deployer.get().addAppProvider(contextProvider); + } + + if (webAppProvider == null) + { + webAppProvider = new BundleWebAppProvider(ENVIRONMENT, server, new EE10WebAppFactory(_myBundle)); + deployer.get().addAppProvider(webAppProvider); + } + + //ensure the providers are configured with the extra bundles that must be scanned from the container classpath + if (containerScanBundlePattern != null) + { + contextProvider.getProperties().put(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, containerScanBundlePattern); + webAppProvider.getProperties().put(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, containerScanBundlePattern); + } + } + else + LOG.info("No DeploymentManager for Server {}", server); + + try + { + if (!server.isStarted()) + server.start(); + } + catch (Exception e) + { + LOG.warn("Failed to start server {}", server); + } + return server; + } + + @Override + public void modifiedService(ServiceReference reference, Object service) + { + removedService(reference, service); + addingService(reference); + } + + @Override + public void removedService(ServiceReference reference, Object service) + { + } + + private Optional getDeploymentManager(Server server) + { + Collection deployers = server.getBeans(DeploymentManager.class); + return deployers.stream().findFirst(); + } + + private List convertBundleToURL(Bundle bundle) + { + List urls = new ArrayList<>(); + try + { + File file = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); + + if (file.isDirectory()) + { + for (File f : file.listFiles()) + { + if (FileID.isJavaArchive(f.getName()) && f.isFile()) + { + urls.add(f.toURI().toURL()); + } + else if (f.isDirectory() && f.getName().equals("lib")) + { + for (File f2 : file.listFiles()) + { + if (FileID.isJavaArchive(f2.getName()) && f2.isFile()) + { + urls.add(f2.toURI().toURL()); + } + } + } + } + urls.add(file.toURI().toURL()); + } + else + { + urls.add(file.toURI().toURL()); + } + } + catch (Exception e) + { + LOG.warn("Unable to convert bundle {} to url", bundle, e); + } + + return urls; + } + } + + public static class EE10ContextFactory implements ContextFactory + { + private Bundle _myBundle; + + public EE10ContextFactory(Bundle bundle) + { + _myBundle = bundle; + } + + @Override + public ContextHandler createContextHandler(AbstractContextProvider provider, App app) + throws Exception + { + OSGiApp osgiApp = OSGiApp.class.cast(app); + String jettyHome = (String)app.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); + Path jettyHomePath = (StringUtil.isBlank(jettyHome) ? null : Paths.get(jettyHome)); + + ContextHandler contextHandler = new ContextHandler(); + + //Make base resource that of the bundle + contextHandler.setBaseResource(osgiApp.getBundleResource()); + + // provides access to core classes + ClassLoader coreLoader = (ClassLoader)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + if (LOG.isDebugEnabled()) + LOG.debug("Core classloader = {}", coreLoader.getClass()); + + //provide access to all ee10 classes + ClassLoader environmentLoader = new OSGiClassLoader(coreLoader, _myBundle); + + //Use a classloader that knows about the common jetty parent loader, and also the bundle + OSGiClassLoader classLoader = new OSGiClassLoader(environmentLoader, osgiApp.getBundle()); + contextHandler.setClassLoader(classLoader); + + //Apply any context xml file + String tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); + final URI contextXmlURI = Util.resolvePathAsLocalizedURI(tmp, osgiApp.getBundle(), jettyHomePath); + + if (contextXmlURI != null) + { + ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(contextHandler.getClassLoader()); + WebAppClassLoader.runWithServerClassAccess(() -> + { + XmlConfiguration xmlConfiguration = new XmlConfiguration(ResourceFactory.of(contextHandler).newResource(contextXmlURI)); + WebAppClassLoader.runWithServerClassAccess(() -> + { + Map properties = new HashMap<>(); + xmlConfiguration.getIdMap().put("Server", osgiApp.getDeploymentManager().getServer()); + properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, osgiApp.getPath().toUri().toString()); + properties.put(OSGiServerConstants.JETTY_HOME, (String)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME)); + xmlConfiguration.getProperties().putAll(properties); + xmlConfiguration.configure(contextHandler); + return null; + }); + return null; + }); + } + catch (Exception e) + { + LOG.warn("Error applying context xml", e); + throw e; + } + finally + { + Thread.currentThread().setContextClassLoader(oldLoader); + } + } + + //osgi Enterprise Spec r4 p.427 + contextHandler.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, osgiApp.getBundle().getBundleContext()); + + //make sure we protect also the osgi dirs specified by OSGi Enterprise spec + String[] targets = contextHandler.getProtectedTargets(); + int length = (targets == null ? 0 : targets.length); + + String[] updatedTargets = null; + if (targets != null) + { + updatedTargets = new String[length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(targets, 0, updatedTargets, 0, length); + } + else + updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); + contextHandler.setProtectedTargets(updatedTargets); + + return contextHandler; + } + } + + public static class EE10WebAppFactory implements ContextFactory + { + private Bundle _myBundle; + + public EE10WebAppFactory(Bundle bundle) + { + _myBundle = bundle; + } + + @Override + public ContextHandler createContextHandler(AbstractContextProvider provider, App app) + throws Exception + { + OSGiApp osgiApp = OSGiApp.class.cast(app); + String jettyHome = (String)app.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); + Path jettyHomePath = (StringUtil.isBlank(jettyHome) ? null : Paths.get(jettyHome)); + + WebAppContext webApp = new WebAppContext(); + + //Apply defaults from the deployer providers + webApp.initializeDefaults(provider.getProperties()); + + // provides access to core classes + ClassLoader coreLoader = (ClassLoader)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + if (LOG.isDebugEnabled()) + LOG.debug("Core classloader = {}", coreLoader); + + //provide access to all ee10 classes + ClassLoader environmentLoader = new OSGiClassLoader(coreLoader, _myBundle); + if (LOG.isDebugEnabled()) + LOG.debug("Environment classloader = {}", environmentLoader); + + //Ensure Configurations.getKnown is called with a classloader that can see all of the ee10 and core classes + + ClassLoader old = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(environmentLoader); + WebAppClassLoader.runWithServerClassAccess(() -> + { + Configurations.getKnown(); + return null; + }); + } + finally + { + Thread.currentThread().setContextClassLoader(old); + } + + webApp.setConfigurations(Configurations.getKnown().stream() + .filter(c -> c.isEnabledByDefault()) + .toArray(Configuration[]::new)); + + //Make a webapp classloader + OSGiWebappClassLoader webAppLoader = new OSGiWebappClassLoader(environmentLoader, webApp, osgiApp.getBundle()); + + //Handle Require-TldBundle + //This is a comma separated list of names of bundles that contain tlds that this webapp uses. + //We add them to the webapp classloader. + String requireTldBundles = (String)osgiApp.getProperties().get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); + + List pathsToTldBundles = Util.getPathsToBundlesBySymbolicNames(requireTldBundles, osgiApp.getBundle().getBundleContext()); + for (Path p : pathsToTldBundles) + webAppLoader.addClassPath(p.toUri().toString()); + + //Set up configuration from manifest headers + //extra classpath + String extraClasspath = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH); + if (extraClasspath != null) + webApp.setExtraClasspath(extraClasspath); + + webApp.setClassLoader(webAppLoader); + + //Take care of extra provider properties + webApp.setAttribute(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, provider.getProperties().get(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN)); + + //TODO needed? + webApp.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundles); + + //Set up some attributes + // rfc66 + webApp.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT, osgiApp.getBundle().getBundleContext()); + + // spring-dm-1.2.1 looks for the BundleContext as a different attribute. + // not a spec... but if we want to support + // org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext + // then we need to do this to: + webApp.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), osgiApp.getBundle().getBundleContext()); + + // also pass the bundle directly. sometimes a bundle does not have a + // bundlecontext. + // it is still useful to have access to the Bundle from the servlet + // context. + webApp.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, osgiApp.getBundle()); + + + // apply any META-INF/context.xml file that is found to configure + // the webapp first + //First try looking for one in /META-INF + URI tmpUri = null; + + URL contextXmlURL = Util.getLocalizedEntry("/META-INF/jetty-webapp-context.xml", osgiApp.getBundle()); + if (contextXmlURL != null) + tmpUri = contextXmlURL.toURI(); + + //Then look in the property OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH and apply the first one + if (contextXmlURL == null) + { + String tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); + if (tmp != null) + { + String[] filenames = tmp.split("[,;]"); + tmpUri = Util.resolvePathAsLocalizedURI(filenames[0], osgiApp.getBundle(), jettyHomePath); + } + } + + //apply a context xml if there is one + if (tmpUri != null) + { + final URI contextXmlUri = tmpUri; + ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(webApp.getClassLoader()); + WebAppClassLoader.runWithServerClassAccess(() -> + { + XmlConfiguration xmlConfiguration = new XmlConfiguration(ResourceFactory.of(webApp).newResource(contextXmlUri)); + WebAppClassLoader.runWithServerClassAccess(() -> + { + Map properties = new HashMap<>(); + xmlConfiguration.getIdMap().put("Server", osgiApp.getDeploymentManager().getServer()); + properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, osgiApp.getPath().toUri().toString()); + properties.put(OSGiServerConstants.JETTY_HOME, (String)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME)); + xmlConfiguration.getProperties().putAll(properties); + xmlConfiguration.configure(webApp); + return null; + }); + return null; + }); + } + catch (Exception e) + { + LOG.warn("Error applying context xml", e); + throw e; + } + finally + { + Thread.currentThread().setContextClassLoader(oldLoader); + } + } + + //ensure the context path is set + webApp.setContextPath(osgiApp.getContextPath()); + + //osgi Enterprise Spec r4 p.427 + webApp.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, osgiApp.getBundle().getBundleContext()); + + //Indicate the webapp has been deployed, so that we don't try and redeploy again + webApp.setAttribute(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK); + + //make sure we protect also the osgi dirs specified by OSGi Enterprise spec + String[] targets = webApp.getProtectedTargets(); + String[] updatedTargets = null; + if (targets != null) + { + updatedTargets = new String[targets.length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(targets, 0, updatedTargets, 0, targets.length); + } + else + updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, targets.length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); + webApp.setProtectedTargets(updatedTargets); + + + Path bundlePath = osgiApp.getPath(); + + Resource bundleResource = osgiApp.getBundleResource(); + + String pathToResourceBase = osgiApp.getPathToResourceBase(); + + //if the path wasn't set or it was ., then it is the root of the bundle's installed location + if (StringUtil.isBlank(pathToResourceBase) || ".".equals(pathToResourceBase)) + { + if (LOG.isDebugEnabled()) + LOG.debug("Webapp base using bundle install location: {}", bundleResource); + webApp.setWarResource(bundleResource); + } + else + { + if (pathToResourceBase.startsWith("/") || pathToResourceBase.startsWith("file:")) + { + //The baseResource is outside of the bundle + Path p = Paths.get(pathToResourceBase); + webApp.setWar(p.toUri().toString()); + if (LOG.isDebugEnabled()) + LOG.debug("Webapp base using absolute location: {}", p); + } + else + { + //The baseResource is relative to the root of the bundle + Resource r = bundleResource.resolve(pathToResourceBase); + webApp.setWarResource(r); + if (LOG.isDebugEnabled()) + LOG.debug("Webapp base using path relative to bundle unpacked install location: {}", r); + } + } + + //web.xml + String tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_WEB_XML_PATH); + if (!StringUtil.isBlank(tmp)) + { + URI webXml = Util.resolvePathAsLocalizedURI(tmp, osgiApp.getBundle(), jettyHomePath); + if (webXml != null) + webApp.setDescriptor(webXml.toString()); + } + + // webdefault-ee10.xml + tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH); + if (tmp != null) + { + URI defaultWebXml = Util.resolvePathAsLocalizedURI(tmp, osgiApp.getBundle(), jettyHomePath); + if (defaultWebXml != null) + { + webApp.setDefaultsDescriptor(defaultWebXml.toString()); + } + } + + return webApp; + } + } + + private PackageAdminServiceTracker _packageAdminServiceTracker; + private ServiceTracker _tracker; + + /** + * Track jetty Server instances and add ability to deploy EE10 contexts/webapps + * + * @param context the bundle context + */ + @Override + public void start(final BundleContext context) throws Exception + { + // track other bundles and fragments attached to this bundle that we + // should activate. + _packageAdminServiceTracker = new PackageAdminServiceTracker(context); + + //track jetty Server instances + _tracker = new ServiceTracker(context, context.createFilter("(objectclass=" + Server.class.getName() + ")"), new ServerTracker(context.getBundle())); + _tracker.open(); + + //register for bundleresource: url resource handling + ResourceFactory.registerResourceFactory("bundleresource", new URLResourceFactory()); + } + + /** + * Stop the activator. + * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception + { + if (_tracker != null) + { + _tracker.close(); + _tracker = null; + } + } +} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/JettyBootstrapActivator.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/JettyBootstrapActivator.java deleted file mode 100644 index faf198a537d..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/JettyBootstrapActivator.java +++ /dev/null @@ -1,126 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.JettyServerServiceTracker; -import org.eclipse.jetty.ee10.osgi.boot.utils.internal.PackageAdminServiceTracker; -import org.eclipse.jetty.server.Server; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JettyBootstrapActivator - *

- * Bootstrap jetty and publish a default Server instance as an OSGi service. - *

- * Listen for other Server instances to be published as services and support them as deployment targets. - *

- * Listen for Bundles to be activated, and deploy those that represent webapps/ContextHandlers to one of the known Server instances. - */ -public class JettyBootstrapActivator implements BundleActivator -{ - private static final Logger LOG = LoggerFactory.getLogger(JettyBootstrapActivator.class); - - private static JettyBootstrapActivator INSTANCE = null; - - public static JettyBootstrapActivator getInstance() - { - return INSTANCE; - } - - private ServiceRegistration _registeredServer; - - private PackageAdminServiceTracker _packageAdminServiceTracker; - - private ServiceTracker _jettyServerServiceTracker; - - /** - * Setup a new jetty Server, registers it as a service. Setup the Service - * tracker for the jetty ContextHandlers that are in charge of deploying the - * webapps. Setup the BundleListener that supports the extender pattern for - * the jetty ContextHandler. - * - * @param context the bundle context - */ - @Override - public void start(final BundleContext context) throws Exception - { - ServiceReference[] references = context.getAllServiceReferences("org.eclipse.jetty.http.HttpFieldPreEncoder", null); - - if (references == null || references.length == 0) - LOG.warn("OSGi support for java.util.ServiceLoader may not be present. You may experience runtime errors."); - - INSTANCE = this; - - // track other bundles and fragments attached to this bundle that we - // should activate. - _packageAdminServiceTracker = new PackageAdminServiceTracker(context); - - // track jetty Server instances that we should support as deployment targets - _jettyServerServiceTracker = new ServiceTracker(context, context.createFilter("(objectclass=" + Server.class.getName() + ")"), new JettyServerServiceTracker()); - _jettyServerServiceTracker.open(); - - // Create a default jetty instance right now. - DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); - } - - /** - * Stop the activator. - * - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception - { - try - { - if (_jettyServerServiceTracker != null) - { - _jettyServerServiceTracker.close(); - _jettyServerServiceTracker = null; - } - if (_packageAdminServiceTracker != null) - { - _packageAdminServiceTracker.stop(); - context.removeServiceListener(_packageAdminServiceTracker); - _packageAdminServiceTracker = null; - } - if (_registeredServer != null) - { - try - { - _registeredServer.unregister(); - } - catch (IllegalArgumentException ill) - { - // already unregistered. - } - finally - { - _registeredServer = null; - } - } - } - finally - { - INSTANCE = null; - } - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiDeployer.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiDeployer.java deleted file mode 100644 index 7e95c81b10f..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiDeployer.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.bindings.StandardDeployer; -import org.eclipse.jetty.deploy.graph.Node; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.utils.EventSender; - -/** - * OSGiDeployer - * - * Extension of standard Jetty deployer that emits OSGi EventAdmin - * events whenever a webapp is deployed into OSGi via Jetty. - */ -public class OSGiDeployer extends StandardDeployer -{ - - private ServerInstanceWrapper _server; - - public OSGiDeployer(ServerInstanceWrapper server) - { - _server = server; - } - - @Override - public void processBinding(Node node, App app) throws Exception - { - //TODO how to NOT send this event if its not a webapp: - //OSGi Enterprise Spec only wants an event sent if its a webapp bundle (ie not a ContextHandler) - if (!(app instanceof AbstractOSGiApp)) - { - doProcessBinding(node, app); - } - else - { - EventSender.getInstance().send(EventSender.DEPLOYING_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); - try - { - doProcessBinding(node, app); - ((AbstractOSGiApp)app).registerAsOSGiService(); - EventSender.getInstance().send(EventSender.DEPLOYED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); - } - catch (Exception e) - { - EventSender.getInstance().send(EventSender.FAILED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); - throw e; - } - } - } - - protected void doProcessBinding(Node node, App app) throws Exception - { - ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(_server.getParentClassLoaderForWebapps()); - try - { - super.processBinding(node, app); - } - finally - { - Thread.currentThread().setContextClassLoader(old); - } - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiMetaInfConfiguration.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiMetaInfConfiguration.java index 4017299c3b5..eba6bd2f489 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiMetaInfConfiguration.java +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiMetaInfConfiguration.java @@ -27,34 +27,34 @@ import java.util.StringTokenizer; import java.util.TreeMap; import java.util.regex.Pattern; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee10.osgi.boot.utils.Util; -import org.eclipse.jetty.ee10.osgi.boot.utils.internal.PackageAdminServiceTracker; import org.eclipse.jetty.ee10.webapp.Configuration; import org.eclipse.jetty.ee10.webapp.MetaInfConfiguration; import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.ee10.webapp.WebInfConfiguration; +import org.eclipse.jetty.osgi.OSGiWebappConstants; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.Util; +import org.eclipse.jetty.util.FileID; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.ResourceCollection; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * OSGiWebInfConfiguration + * OSGiMetaInfConfiguration * - * Handle adding resources found in bundle fragments, and add them into the + * Handle adding resources found in bundles. */ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { - private static final Logger LOG = LoggerFactory.getLogger(WebInfConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(OSGiMetaInfConfiguration.class); /** * Comma separated list of symbolic names of bundles that contain tlds that should be considered * as on the container classpath */ - public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.ee10.osgi.tldbundles"; + public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles"; /** * Regex of symbolic names of bundles that should be considered to be on the container classpath */ @@ -108,28 +108,30 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration names.add(tokenizer.nextToken()); } } - HashSet matchingResources = new HashSet(); + + HashSet matchingResources = new HashSet<>(); if (!names.isEmpty() || pattern != null) { Bundle[] bundles = FrameworkUtil.getBundle(OSGiMetaInfConfiguration.class).getBundleContext().getBundles(); for (Bundle bundle : bundles) { - LOG.debug("Checking bundle {}:{}", bundle.getBundleId(), bundle.getSymbolicName()); + if (LOG.isDebugEnabled()) + LOG.debug("Checking bundle {}:{}", bundle.getBundleId(), bundle.getSymbolicName()); if (pattern != null) { // if bundle symbolic name matches the pattern if (pattern.matcher(bundle.getSymbolicName()).matches()) { //get the file location of the jar and put it into the list of container jars that will be scanned for stuff (including tlds) - matchingResources.addAll(getBundleAsResource(bundle)); + matchingResources.addAll(getBundleAsResource(ResourceFactory.of(context), bundle)); } } if (names != null) { //if there is an explicit bundle name, then check if it matches if (names.contains(bundle.getSymbolicName())) - matchingResources.addAll(getBundleAsResource(bundle)); + matchingResources.addAll(getBundleAsResource(ResourceFactory.of(context), bundle)); } } } @@ -168,6 +170,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration Bundle[] bundles = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles((Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE)); if (bundles != null && bundles.length > 0) { + @SuppressWarnings("unchecked") Set fragsAndReqsBundles = (Set)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES); if (fragsAndReqsBundles == null) { @@ -175,6 +178,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, fragsAndReqsBundles); } + @SuppressWarnings("unchecked") Set fragsAndReqsResources = (Set)context.getAttribute(FRAGMENT_AND_REQUIRED_RESOURCES); if (fragsAndReqsResources == null) { @@ -191,7 +195,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration //add to context attribute storing associated fragments and required bundles fragsAndReqsBundles.add(b); File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(b); - Resource r = Resource.newResource(f.toURI()); + Resource r = ResourceFactory.of(context).newResource(f.toURI()); //add to convenience context attribute storing fragments and required bundles as Resources fragsAndReqsResources.add(r); mergedResources.add(r); @@ -217,6 +221,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE); if (bundle != null) { + @SuppressWarnings("unchecked") Set fragments = (Set)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES); if (fragments != null && !fragments.isEmpty()) { @@ -236,14 +241,15 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration for (Bundle frag : fragments) { String path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_FRAGMENT_RESOURCE_PATH, frag.getHeaders()); - convertFragmentPathToResource(path, frag, appendedResourcesPath); + convertFragmentPathToResource(ResourceFactory.of(context), path, frag, appendedResourcesPath); path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_PREPEND_FRAGMENT_RESOURCE_PATH, frag.getHeaders()); - convertFragmentPathToResource(path, frag, prependedResourcesPath); + convertFragmentPathToResource(ResourceFactory.of(context), path, frag, prependedResourcesPath); } if (!appendedResourcesPath.isEmpty()) { - LinkedHashSet resources = new LinkedHashSet(); + LinkedHashSet resources = new LinkedHashSet<>(); //Add in any existing setting of extra resource dirs + @SuppressWarnings("unchecked") Set resourceDirs = (Set)context.getAttribute(MetaInfConfiguration.RESOURCE_DIRS); if (resourceDirs != null && !resourceDirs.isEmpty()) resources.addAll(resourceDirs); @@ -263,8 +269,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration Resource[] resources = new Resource[1 + prependedResourcesPath.size()]; System.arraycopy(prependedResourcesPath.values().toArray(new Resource[prependedResourcesPath.size()]), 0, resources, 0, prependedResourcesPath.size()); resources[resources.length - 1] = context.getBaseResource(); - - context.setBaseResource(Resource.of(resources)); + context.setBaseResource(ResourceFactory.combine(resources)); } } @@ -272,10 +277,10 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration * Resolves the bundle. Usually that would be a single URL per bundle. But we do some more work if there are jars * embedded in the bundle. */ - private List getBundleAsResource(Bundle bundle) + private List getBundleAsResource(ResourceFactory resourceFactory, Bundle bundle) throws Exception { - List resources = new ArrayList(); + List resources = new ArrayList<>(); File file = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); if (file.isDirectory()) @@ -284,7 +289,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { if (FileID.isJavaArchive(f.getName()) && f.isFile()) { - resources.add(Resource.newResource(f)); + resources.add(resourceFactory.newResource(f.toPath())); } else if (f.isDirectory() && f.getName().equals("lib")) { @@ -292,16 +297,16 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { if (FileID.isJavaArchive(f2.getName()) && f2.isFile()) { - resources.add(Resource.newResource(f)); + resources.add(resourceFactory.newResource(f.toPath())); } } } } - resources.add(Resource.newResource(file)); //TODO really??? + resources.add(resourceFactory.newResource(file.toPath())); //TODO really??? } else { - resources.add(Resource.newResource(file)); + resources.add(resourceFactory.newResource(file.toPath())); } return resources; @@ -310,7 +315,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration /** * Convert a path inside a fragment into a Resource */ - private void convertFragmentPathToResource(String resourcePath, Bundle fragment, Map resourceMap) + private void convertFragmentPathToResource(ResourceFactory resourceFactory, String resourcePath, Bundle fragment, Map resourceMap) throws Exception { if (resourcePath == null) @@ -333,6 +338,6 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { uri = new URI(url.toString().replaceAll(" ", "%20")); } - resourceMap.put(key + ";" + fragment.getSymbolicName(), Resource.newResource(uri)); + resourceMap.put(key + ";" + fragment.getSymbolicName(), resourceFactory.newResource(uri)); } } diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiServerConstants.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiServerConstants.java deleted file mode 100644 index 3fbc39e973a..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiServerConstants.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -/** - * OSGiServerConstants - * - * Name of the properties that configure a jetty Server OSGi service. - */ -public class OSGiServerConstants -{ - /** - * Usual system property used as the hostname for a typical jetty - * configuration. - */ - public static final String JETTY_HOME = "jetty.home"; - public static final String JETTY_BASE = "jetty.base"; - - /** - * System property to point to a bundle that embeds a jetty configuration - * and that jetty configuration should be the default jetty server. First we - * look for jetty.home. If we don't find it then we look for this property. - */ - public static final String JETTY_HOME_BUNDLE = "jetty.home.bundle"; - - /** - * Usual system property used as the hostname for a typical jetty - * configuration. - */ - public static final String JETTY_HOST = "jetty.http.host"; - - /** - * Usual system property used as the port for http for a typical jetty - * configuration. - */ - public static final String JETTY_PORT = "jetty.http.port"; - - /** - * Usual system property used as the port for https for a typical jetty - * configuration. - */ - public static final String JETTY_PORT_SSL = "jetty.ssl.port"; - - //for managed jetty instances, name of the configuration parameters - /** - * PID of the jetty servers's ManagedFactory - */ - public static final String MANAGED_JETTY_SERVER_FACTORY_PID = "org.eclipse.jetty.ee10.osgi.boot.managedserverfactory"; - - /** - * The associated value of that configuration parameter is the name under which this - * instance of the jetty server is tracked. - * When a ContextHandler is deployed and it specifies the managedServerName property, it is deployed - * on the corresponding jetty managed server or it throws an exception: jetty server not available. - */ - public static final String MANAGED_JETTY_SERVER_NAME = "managedServerName"; - /** - * Name of the 'default' jetty server instance. - * Usually the first one to be created. - */ - public static final String MANAGED_JETTY_SERVER_DEFAULT_NAME = "defaultJettyServer"; - - /** - * List of URLs to the jetty.xml files that configure th server. - */ - public static final String MANAGED_JETTY_XML_CONFIG_URLS = "jetty.etc.config.urls"; - - /** - * List of URLs to the folders where the legacy J2EE shared libraries are stored aka lib/ext, lib/jsp etc. - */ - public static final String MANAGED_JETTY_SHARED_LIB_FOLDER_URLS = "managedJettySharedLibFolderUrls"; -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiUndeployer.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiUndeployer.java deleted file mode 100644 index 9185ab7fe55..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiUndeployer.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.bindings.StandardUndeployer; -import org.eclipse.jetty.deploy.graph.Node; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.utils.EventSender; - -/** - * OSGiUndeployer - * - * Extension of the Jetty Undeployer which emits OSGi EventAdmin events - * whenever a webapp is undeployed from Jetty. - */ -public class OSGiUndeployer extends StandardUndeployer -{ - private ServerInstanceWrapper _server; - - public OSGiUndeployer(ServerInstanceWrapper server) - { - _server = server; - } - - @Override - public void processBinding(Node node, App app) throws Exception - { - EventSender.getInstance().send(EventSender.UNDEPLOYING_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); - ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(_server.getParentClassLoaderForWebapps()); - try - { - super.processBinding(node, app); - } - finally - { - Thread.currentThread().setContextClassLoader(old); - } - EventSender.getInstance().send(EventSender.UNDEPLOYED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath()); - ((AbstractOSGiApp)app).deregisterAsOSGiService(); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebInfConfiguration.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebInfConfiguration.java deleted file mode 100644 index e17bc9f1de2..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebInfConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import org.eclipse.jetty.ee10.webapp.Configuration; -import org.eclipse.jetty.ee10.webapp.WebInfConfiguration; - -/** - * OSGiWebInfConfiguration - * - * Handle adding resources found in bundle fragments, and add them into the - */ -public class OSGiWebInfConfiguration extends WebInfConfiguration -{ - @Override - public Class replaces() - { - return WebInfConfiguration.class; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/webapp/OSGiWebappClassLoader.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappClassLoader.java similarity index 54% rename from jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/webapp/OSGiWebappClassLoader.java rename to jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappClassLoader.java index 03b46c39650..90caa83af47 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/webapp/OSGiWebappClassLoader.java +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappClassLoader.java @@ -11,24 +11,15 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.osgi.boot.internal.webapp; +package org.eclipse.jetty.ee10.osgi.boot; -import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.ArrayList; import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.jar.JarFile; -import jakarta.servlet.http.HttpServlet; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleClassLoaderHelperFactory; import org.eclipse.jetty.ee10.webapp.WebAppClassLoader; import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.osgi.util.BundleClassLoaderHelperFactory; import org.osgi.framework.Bundle; import org.osgi.framework.BundleReference; import org.slf4j.Logger; @@ -42,30 +33,8 @@ import org.slf4j.LoggerFactory; */ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleReference { - private static final Logger LOG = LoggerFactory.getLogger(OSGiWebappClassLoader.class.getName()); - /** - * when a logging framework is setup in the osgi classloaders, it can access - * this and register the classes that must not be found in the jar. - */ - public static final Set JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED = new HashSet<>(); - - public static void addClassThatIdentifiesAJarThatMustBeRejected(Class zclass) - { - JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(TypeUtil.toClassReference(zclass.getName())); - } - - public static void addClassThatIdentifiesAJarThatMustBeRejected(String zclassName) - { - JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(TypeUtil.toClassReference(zclassName)); - } - - static - { - addClassThatIdentifiesAJarThatMustBeRejected(HttpServlet.class); - } - private ClassLoader _osgiBundleClassLoader; private Bundle _contributor; @@ -171,91 +140,4 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe } } } - - private List toList(Enumeration e, Enumeration e2) - { - List list = new ArrayList<>(); - while (e != null && e.hasMoreElements()) - { - list.add(e.nextElement()); - } - while (e2 != null && e2.hasMoreElements()) - { - list.add(e2.nextElement()); - } - return list; - } - - /** - * Parse the classpath ourselves to be able to filter things. This is a - * derivative work of the super class - */ - @Override - public void addClassPath(String classPath) throws IOException - { - for (Resource resource : Resource.fromList(classPath, false, (path) -> getContext().newResource(path))) - { - File file = resource.getFile(); - if (file != null && isAcceptableLibrary(file, JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED)) - { - super.addClassPath(resource); - } - else - { - LOG.info("Did not add {} to the classloader of the webapp {}", resource, getContext()); - } - } - } - - /** - * @return true if the lib should be included in the webapp classloader. - */ - private boolean isAcceptableLibrary(File file, Set pathToClassFiles) - { - try - { - if (file.isDirectory()) - { - for (String criteria : pathToClassFiles) - { - if (new File(file, criteria).exists()) - { - return false; - } - } - } - else - { - JarFile jar = null; - try - { - jar = new JarFile(file); - for (String criteria : pathToClassFiles) - { - if (jar.getEntry(criteria) != null) - { - return false; - } - } - } - finally - { - if (jar != null) - try - { - jar.close(); - } - catch (IOException ignored) - { - } - } - } - } - catch (IOException e) - { - // nevermind. just trying our best - LOG.trace("IGNORED", e); - } - return true; - } } diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappConstants.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappConstants.java deleted file mode 100644 index dfc5a9fa647..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappConstants.java +++ /dev/null @@ -1,138 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -/** - * OSGiWebappConstants - * - * - * Constants (MANIFEST headers, service properties etc) associated with deploying - * webapps into OSGi via Jetty. - */ -public class OSGiWebappConstants -{ - /** - * service property osgi.web.symbolicname. See OSGi r4 - */ - public static final String OSGI_WEB_SYMBOLICNAME = "osgi.web.symbolicname"; - - /** - * service property osgi.web.symbolicname. See OSGi r4 - */ - public static final String OSGI_WEB_VERSION = "osgi.web.version"; - - /** - * service property osgi.web.contextpath. See OSGi r4 - */ - public static final String OSGI_WEB_CONTEXTPATH = "osgi.web.contextpath"; - - /** - * See OSGi r4 p.427 - */ - public static final String OSGI_BUNDLECONTEXT = "osgi-bundlecontext"; - - /** - * url scheme to deploy war file as bundled webapp - */ - public static final String RFC66_WAR_URL_SCHEME = "war"; - - /** - * Name of the header that defines the context path for the embedded webapp. - */ - public static final String RFC66_WEB_CONTEXTPATH = "Web-ContextPath"; - - /** - * Name of the header that defines the path to the folder where the jsp - * files are extracted. - */ - public static final String RFC66_JSP_EXTRACT_LOCATION = "Jsp-ExtractLocation"; - - /** - * Name of the servlet context attribute that points to the bundle context. - */ - public static final String RFC66_OSGI_BUNDLE_CONTEXT = "osgi-bundlecontext"; - - /** - * Name of the servlet context attribute that points to the bundle object. - * We can't always rely on the bundle-context as there might be no such thing. - */ - public static final String JETTY_OSGI_BUNDLE = "osgi-bundle"; - - /** - * List of relative pathes within the bundle to the jetty context files. - */ - public static final String JETTY_CONTEXT_FILE_PATH = "Jetty-ContextFilePath"; - - /** - * path within the bundle to the folder that contains the basic resources. - */ - public static final String JETTY_WAR_RESOURCE_PATH = "Jetty-WarResourcePath"; - - /** - * path within a fragment hosted by a web-bundle to a folder that contains basic resources. - * the path is appended to the lookup path where jetty locates static resources - */ - public static final String JETTY_WAR_FRAGMENT_RESOURCE_PATH = "Jetty-WarFragmentResourcePath"; - - /** - * path within a fragment hosted by a web-bundle to a folder that contains basic resources. - * The path is prefixed to the lookup path where jetty locates static resources: - * this will override static resources with the same name in the web-bundle. - */ - public static final String JETTY_WAR_PREPEND_FRAGMENT_RESOURCE_PATH = "Jetty-WarPrependFragmentResourcePath"; - - /** - * installation path of webapp bundle - */ - public static final String JETTY_BUNDLE_ROOT = "bundle.root"; - - /** - * Extra classpath - */ - public static final String JETTY_EXTRA_CLASSPATH = "Jetty-extraClasspath"; - - /** - * web.xml file path - */ - public static final String JETTY_WEB_XML_PATH = "Jetty-WebXmlFilePath"; - - /** - * defaultweb.xml file path - */ - public static final String JETTY_DEFAULT_WEB_XML_PATH = "Jetty-defaultWebXmlFilePath"; - - /** - * path to the base folder that overrides the computed bundle installation - * location if not null useful to install webapps or jetty context files - * that are in fact not embedded in a bundle - */ - public static final String JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE = "Jetty-bundleInstall"; - - /** - * Comma separated list of bundles that contain tld file used by the webapp. - */ - public static final String REQUIRE_TLD_BUNDLE = "Require-TldBundle"; - /** - * Comma separated list of bundles that contain tld file used by the webapp. - * Both the name of the manifest header and the name of the service property. - */ - public static final String SERVICE_PROP_REQUIRE_TLD_BUNDLE = REQUIRE_TLD_BUNDLE; - - public static final String WATERMARK = "o.e.j.o.b.watermark"; - - /** - * Set of extra dirs that must not be served by osgi webapps - */ - public static final String[] DEFAULT_PROTECTED_OSGI_TARGETS = {"/osgi-inf", "/osgi-opts"}; -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/PackageAdminServiceTracker.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/PackageAdminServiceTracker.java similarity index 92% rename from jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/PackageAdminServiceTracker.java rename to jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/PackageAdminServiceTracker.java index d7a31cdd394..636aeecbf70 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/PackageAdminServiceTracker.java +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/PackageAdminServiceTracker.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.osgi.boot.utils.internal; +package org.eclipse.jetty.ee10.osgi.boot; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -28,6 +28,8 @@ import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.startlevel.StartLevel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * PackageAdminServiceTracker @@ -35,11 +37,12 @@ import org.osgi.service.startlevel.StartLevel; * When the PackageAdmin service is activated we can look for the fragments * attached to this bundle and do a fake "activate" on them. *

- * See particularly the jetty-ee10-osgi-boot-jsp fragment bundle that uses this + * See particularly the jetty-ee9-osgi-boot-jsp fragment bundle that uses this * facility. */ public class PackageAdminServiceTracker implements ServiceListener { + private static Logger LOG = LoggerFactory.getLogger(PackageAdminServiceTracker.class); private BundleContext _context; private List _activatedFragments = new ArrayList<>(); @@ -55,19 +58,13 @@ public class PackageAdminServiceTracker implements ServiceListener public static PackageAdminServiceTracker INSTANCE = null; public PackageAdminServiceTracker(BundleContext context) + throws Exception { INSTANCE = this; _context = context; if (!setup()) { - try - { - _context.addServiceListener(this, "(objectclass=" + PackageAdmin.class.getName() + ")"); - } - catch (InvalidSyntaxException e) - { - e.printStackTrace(); // won't happen - } + _context.addServiceListener(this, "(objectclass=" + PackageAdmin.class.getName() + ")"); } } @@ -75,6 +72,7 @@ public class PackageAdminServiceTracker implements ServiceListener * @return true if the fragments were activated by this method. */ private boolean setup() + throws Exception { ServiceReference sr = _context.getServiceReference(PackageAdmin.class.getName()); _fragmentsWereActivated = sr != null; @@ -111,7 +109,14 @@ public class PackageAdminServiceTracker implements ServiceListener { if (event.getType() == ServiceEvent.REGISTERED) { - invokeFragmentActivators(event.getServiceReference()); + try + { + invokeFragmentActivators(event.getServiceReference()); + } + catch (Exception e) + { + LOG.warn("Error invoking fragment activators", e); + } } } @@ -271,6 +276,7 @@ public class PackageAdminServiceTracker implements ServiceListener } private void invokeFragmentActivators(ServiceReference sr) + throws Exception { PackageAdmin admin = (PackageAdmin)_context.getService(sr); Bundle[] fragments = admin.getFragments(_context.getBundle()); @@ -281,20 +287,13 @@ public class PackageAdminServiceTracker implements ServiceListener for (Bundle frag : fragments) { // find a convention to look for a class inside the fragment. - try + String fragmentActivator = frag.getSymbolicName() + ".FragmentActivator"; + Class c = Class.forName(fragmentActivator); + if (c != null) { - String fragmentActivator = frag.getSymbolicName() + ".FragmentActivator"; - Class c = Class.forName(fragmentActivator); - if (c != null) - { - BundleActivator bActivator = (BundleActivator)c.getDeclaredConstructor().newInstance(); - bActivator.start(_context); - _activatedFragments.add(bActivator); - } - } - catch (Exception e) - { - e.printStackTrace(); + BundleActivator bActivator = (BundleActivator)c.getDeclaredConstructor().newInstance(); + bActivator.start(_context); + _activatedFragments.add(bActivator); } } } diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceContextProvider.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceContextProvider.java deleted file mode 100644 index 2fdb662d471..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceContextProvider.java +++ /dev/null @@ -1,224 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.utils.Util; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.Filter; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ServiceContextProvider - * - * Jetty DeploymentManager Provider that is able to deploy ContextHandlers discovered via OSGi as services. - */ -public class ServiceContextProvider extends AbstractContextProvider implements ServiceProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); - - private Map _serviceMap = new HashMap<>(); - - private ServiceRegistration _serviceRegForServices; - - ServiceTracker _tracker; - - /** - * ContextTracker - */ - public class ContextTracker extends ServiceTracker - { - - public ContextTracker(BundleContext bundleContext, Filter filter) - { - super(bundleContext, filter, null); - } - - @Override - public Object addingService(ServiceReference reference) - { - ContextHandler h = (ContextHandler)context.getService(reference); - serviceAdded(reference, h); - return h; - } - - @Override - public void modifiedService(ServiceReference reference, Object service) - { - removedService(reference, service); - addingService(reference); - } - - @Override - public void removedService(ServiceReference reference, Object service) - { - context.ungetService(reference); - serviceRemoved(reference, (ContextHandler)service); - } - } - - /** - * ServiceApp - */ - public class ServiceApp extends OSGiApp - { - public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String contextFile, String originId) - { - super(manager, provider, bundle, properties, contextFile, originId); - } - - public ServiceApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile) - { - super(manager, provider, originId, bundle, contextFile); - } - - @Override - public void registerAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - - @Override - protected void deregisterAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - } - - public ServiceContextProvider(ServerInstanceWrapper wrapper) - { - super(wrapper); - } - - @Override - public boolean serviceAdded(ServiceReference serviceRef, ContextHandler context) - { - if (context == null || serviceRef == null) - return false; - - if (context instanceof org.eclipse.jetty.ee10.webapp.WebAppContext) - return false; //the ServiceWebAppProvider will deploy it - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a contexthandler that has already been registered as a service by another of our deployers - - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps()); - try - { - //See if there is a context file to apply to this pre-made context - String contextFile = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); - - String[] keys = serviceRef.getPropertyKeys(); - Dictionary properties = new Hashtable<>(); - if (keys != null) - { - for (String key : keys) - { - properties.put(key, serviceRef.getProperty(key)); - } - } - Bundle bundle = serviceRef.getBundle(); - String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-" + (contextFile != null ? contextFile : serviceRef.getProperty(Constants.SERVICE_ID)); - ServiceApp app = new ServiceApp(getDeploymentManager(), this, bundle, properties, contextFile, originId); - app.setHandler(context); //set the pre=made ContextHandler instance - _serviceMap.put(serviceRef, app); - getDeploymentManager().addApp(app); - return true; - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - - @Override - public boolean serviceRemoved(ServiceReference serviceRef, ContextHandler context) - { - - if (context == null || serviceRef == null) - return false; - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a contexthandler that will be deregistered as a service by another of our deployers - - App app = _serviceMap.remove(serviceRef); - if (app != null) - { - getDeploymentManager().removeApp(app); - return true; - } - - return false; - } - - @Override - protected void doStart() throws Exception - { - - BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); - - //Start a tracker to find webapps that are osgi services that are targeted to my server name - _tracker = new ContextTracker(bundleContext, - Util.createFilter(bundleContext, ContextHandler.class.getName(), getServerInstanceWrapper().getManagedServerName())); - _tracker.open(); - - //register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to - Dictionary properties = new Hashtable<>(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); - - //register as an osgi service for deploying contexts, advertising the name of the jetty Server instance we are related to - _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties); - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - if (_tracker != null) - _tracker.close(); - - //unregister ourselves - if (_serviceRegForServices != null) - { - try - { - _serviceRegForServices.unregister(); - } - catch (Exception e) - { - LOG.warn("Unable to unregister {}", _serviceRegForServices, e); - } - } - super.doStop(); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceProvider.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceProvider.java deleted file mode 100644 index 68f26c98370..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.ServiceReference; - -/** - * ServiceProvider - * - * Jetty DeploymentManager Provider api for webapps or ContextHandlers that are discovered as OSGi services. - */ -public interface ServiceProvider -{ - public boolean serviceAdded(ServiceReference ref, ContextHandler handler) throws Exception; - - public boolean serviceRemoved(ServiceReference ref, ContextHandler handler) throws Exception; -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceWebAppProvider.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceWebAppProvider.java deleted file mode 100644 index 85dd13ae5c2..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/ServiceWebAppProvider.java +++ /dev/null @@ -1,256 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot; - -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee10.osgi.boot.utils.Util; -import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Filter; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ServiceWebAppProvider - *

- * Jetty Provider that knows how to deploy a WebApp that has been registered as an OSGi service. - */ -public class ServiceWebAppProvider extends AbstractWebAppProvider implements ServiceProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); - - /** - * Map of ServiceRef to App. Used when it is an osgi service that is a WebAppContext. - */ - private Map _serviceMap = new HashMap<>(); - - private ServiceRegistration _serviceRegForServices; - - private ServiceTracker webappTracker; - - /** - * WebAppTracker - */ - public class WebAppTracker extends ServiceTracker - { - /** - * @param bundleContext the osgi context - * @param filter the osgi filter for the tracker - */ - public WebAppTracker(BundleContext bundleContext, Filter filter) - { - super(bundleContext, filter, null); - } - - @Override - public Object addingService(ServiceReference reference) - { - WebAppContext wac = (WebAppContext)context.getService(reference); - serviceAdded(reference, wac); - return wac; - } - - @Override - public void modifiedService(ServiceReference reference, Object service) - { - removedService(reference, service); - addingService(reference); - } - - @Override - public void removedService(ServiceReference reference, Object service) - { - serviceRemoved(reference, (WebAppContext)service); - context.ungetService(reference); - } - } - - /** - * ServiceApp - */ - public class ServiceApp extends OSGiApp - { - - public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId) - { - super(manager, provider, bundle, properties, originId); - } - - public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId) - { - super(manager, provider, bundle, originId); - } - - @Override - public void registerAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - - @Override - protected void deregisterAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - } - - public ServiceWebAppProvider(ServerInstanceWrapper wrapper) - { - super(wrapper); - } - - /** - * A webapp that was deployed as an osgi service has been added, - * and we want to deploy it. - * - * @param context the webapp - */ - @Override - public boolean serviceAdded(ServiceReference serviceRef, ContextHandler context) - { - if (context == null || !(context instanceof WebAppContext)) - return false; - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a webapp that has already been registered as a service by another of our deployers - - WebAppContext webApp = (WebAppContext)context; - Dictionary properties = new Hashtable<>(); - - String contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - if (contextPath == null) - return false; //No context path - - String base = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH); - - if (base == null) - return false; //No webapp base - - String webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH); - if (webdefaultXml != null) - properties.put(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH, webdefaultXml); - - String webXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WEB_XML_PATH); - if (webXml != null) - properties.put(OSGiWebappConstants.JETTY_WEB_XML_PATH, webXml); - - String extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH); - if (extraClassPath != null) - properties.put(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH, extraClassPath); - - String bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); - if (bundleInstallOverride != null) - properties.put(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE, bundleInstallOverride); - - String requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); - if (requiredTlds == null) - requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE); - if (requiredTlds != null) - properties.put(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requiredTlds); - - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps()); - try - { - String originId = getOriginId(serviceRef.getBundle(), base); - ServiceApp app = new ServiceApp(getDeploymentManager(), this, serviceRef.getBundle(), properties, originId); - app.setContextPath(contextPath); - app.setWebAppPath(base); - app.setWebAppContext(webApp); //set the pre=made webapp instance - _serviceMap.put(serviceRef, app); - getDeploymentManager().addApp(app); - return true; - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - - /** - * @param context the webapp - */ - @Override - public boolean serviceRemoved(ServiceReference serviceRef, ContextHandler context) - { - if (context == null || !(context instanceof WebAppContext)) - return false; - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a contexthandler that will be deregistered as a service by another of our deployers - - App app = _serviceMap.remove(serviceRef); - if (app != null) - { - getDeploymentManager().removeApp(app); - return true; - } - return false; - } - - @Override - protected void doStart() throws Exception - { - BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); - - //Start a tracker to find webapps that are osgi services that are targeted to my server name - webappTracker = new WebAppTracker(bundleContext, - Util.createFilter(bundleContext, WebAppContext.class.getName(), getServerInstanceWrapper().getManagedServerName())); - webappTracker.open(); - - //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to - Dictionary properties = new Hashtable<>(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); - - //register as an osgi service for deploying contexts (discovered as osgi services), advertising the name of the jetty Server instance we are related to - _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties); - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - webappTracker.close(); - - //unregister ourselves - if (_serviceRegForServices != null) - { - try - { - _serviceRegForServices.unregister(); - } - catch (Exception e) - { - LOG.warn("Unable to unregister {}", _serviceRegForServices, e); - } - } - super.doStop(); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java deleted file mode 100644 index 0d292e44e79..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory; - -import java.util.Dictionary; -import java.util.Hashtable; - -import org.eclipse.jetty.ee10.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.server.Server; -import org.osgi.framework.Bundle; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.ServiceTrackerCustomizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JettyServerServiceTracker - * - * Tracks instances of Jetty Servers, and configures them so that they can deploy - * webapps or ContextHandlers discovered from the OSGi environment. - */ -public class JettyServerServiceTracker implements ServiceTrackerCustomizer -{ - private static Logger LOG = LoggerFactory.getLogger(JettyServerServiceTracker.class.getName()); - - @Override - public Object addingService(ServiceReference sr) - { - Bundle contributor = sr.getBundle(); - Server server = (Server)contributor.getBundleContext().getService(sr); - String name = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - if (name == null) - { - throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); - } - if (LOG.isDebugEnabled()) - LOG.debug("Adding Server {}", name); - ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name); - Dictionary props = new Hashtable<>(); - for (String key : sr.getPropertyKeys()) - { - props.put(key, sr.getProperty(key)); - } - try - { - wrapper.start(server, props); - LOG.info("Started Server {}", name); - return wrapper; - } - catch (Exception e) - { - LOG.warn("Failed to start server {}", name, e); - return sr.getBundle().getBundleContext().getService(sr); - } - } - - @Override - public void modifiedService(ServiceReference reference, Object service) - { - removedService(reference, service); - addingService(reference); - } - - @Override - public void removedService(ServiceReference reference, Object service) - { - if (service instanceof ServerInstanceWrapper) - { - ServerInstanceWrapper wrapper = (ServerInstanceWrapper)service; - try - { - wrapper.stop(); - LOG.info("Stopped Server {}", wrapper.getManagedServerName()); - } - catch (Exception e) - { - LOG.warn("Failed to stop server {}", wrapper.getManagedServerName(), e); - } - } - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java deleted file mode 100644 index adf7d363f4e..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java +++ /dev/null @@ -1,441 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.internal.serverfactory; - -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -import org.eclipse.jetty.deploy.AppLifeCycle; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.deploy.bindings.StandardStarter; -import org.eclipse.jetty.deploy.bindings.StandardStopper; -import org.eclipse.jetty.ee10.osgi.boot.BundleContextProvider; -import org.eclipse.jetty.ee10.osgi.boot.BundleWebAppProvider; -import org.eclipse.jetty.ee10.osgi.boot.JettyBootstrapActivator; -import org.eclipse.jetty.ee10.osgi.boot.OSGiDeployer; -import org.eclipse.jetty.ee10.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.ee10.osgi.boot.OSGiUndeployer; -import org.eclipse.jetty.ee10.osgi.boot.ServiceContextProvider; -import org.eclipse.jetty.ee10.osgi.boot.ServiceWebAppProvider; -import org.eclipse.jetty.ee10.osgi.boot.internal.webapp.LibExtClassLoaderHelper; -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee10.osgi.boot.utils.FakeURLClassLoader; -import org.eclipse.jetty.ee10.osgi.boot.utils.TldBundleDiscoverer; -import org.eclipse.jetty.ee10.osgi.boot.utils.Util; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ServerInstanceWrapper - * - * Configures and starts a jetty Server instance. - */ -public class ServerInstanceWrapper -{ - - /** - * The value of this property points to the parent director of the jetty.xml - * configuration file currently executed. Everything is passed as a URL to - * support the case where the bundle is zipped. - */ - public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url"; - - private static Collection __containerTldBundleDiscoverers = new ArrayList<>(); - - private static final Logger LOG = LoggerFactory.getLogger(ServerInstanceWrapper.class.getName()); - - private final String _managedServerName; - - /** - * The managed jetty server - */ - private Server _server; - - private ContextHandlerCollection _ctxtCollection; - - /** - * This is the class loader that should be the parent classloader of any - * webapp classloader. It is in fact the _libExtClassLoader with a trick to - * let the TldScanner find the jars where the tld files are. - */ - private ClassLoader _commonParentClassLoaderForWebapps; - - private DeploymentManager _deploymentManager; - - public static void addContainerTldBundleDiscoverer(TldBundleDiscoverer tldBundleDiscoverer) - { - __containerTldBundleDiscoverers.add(tldBundleDiscoverer); - } - - public static Collection getContainerTldBundleDiscoverers() - { - return __containerTldBundleDiscoverers; - } - - public static Server configure(Server server, List jettyConfigurations, Dictionary props) throws Exception - { - - if (jettyConfigurations == null || jettyConfigurations.isEmpty()) - { - return server; - } - - Map idMap = new HashMap<>(); - if (server != null) - { - //Put in a mapping for the id "Server" and the name of the server as the instance being configured - idMap.put("Server", server); - idMap.put((String)props.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME), server); - } - - Map properties = new HashMap<>(); - if (props != null) - { - Enumeration en = props.keys(); - while (en.hasMoreElements()) - { - String key = en.nextElement(); - Object value = props.get(key); - properties.put(key, value.toString()); - if (server != null) - server.setAttribute(key, value); - } - } - - for (URL jettyConfiguration : jettyConfigurations) - { - try - { - // Execute a Jetty configuration file - XmlConfiguration config = new XmlConfiguration(Resource.newResource(jettyConfiguration)); - - config.getIdMap().putAll(idMap); - config.getProperties().putAll(properties); - - // #334062 compute the URL of the folder that contains the - // conf file and set it as a property so we can compute relative paths - // from it. - String urlPath = jettyConfiguration.toString(); - int lastSlash = urlPath.lastIndexOf('/'); - if (lastSlash > 4) - { - urlPath = urlPath.substring(0, lastSlash); - config.getProperties().put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath); - } - - Object o = config.configure(); - if (server == null) - server = (Server)o; - - idMap = config.getIdMap(); - } - catch (Exception e) - { - LOG.warn("Configuration error in {}", jettyConfiguration); - throw e; - } - } - - return server; - } - - public ServerInstanceWrapper(String managedServerName) - { - _managedServerName = managedServerName; - } - - public String getManagedServerName() - { - return _managedServerName; - } - - /** - * The classloader that should be the parent classloader for each webapp - * deployed on this server. - * - * @return the classloader - */ - public ClassLoader getParentClassLoaderForWebapps() - { - return _commonParentClassLoaderForWebapps; - } - - /** - * @return The deployment manager registered on this server. - */ - public DeploymentManager getDeploymentManager() - { - return _deploymentManager; - } - - /** - * @return The app provider registered on this server. - */ - public Server getServer() - { - return _server; - } - - /** - * @return The collection of context handlers - */ - public ContextHandlerCollection getContextHandlerCollection() - { - return _ctxtCollection; - } - - public void start(Server server, Dictionary props) throws Exception - { - _server = server; - ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); - try - { - List sharedURLs = getManagedJettySharedLibFolderUrls(props); - - // passing this bundle's classloader as the context classloader - // makes sure there is access to all the jetty's bundles - ClassLoader libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(null, sharedURLs, JettyBootstrapActivator.class.getClassLoader()); - - if (LOG.isDebugEnabled()) - LOG.debug("LibExtClassLoader = {}", libExtClassLoader); - - Thread.currentThread().setContextClassLoader(libExtClassLoader); - - String jettyConfigurationUrls = (String)props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS); - List jettyConfigurations = jettyConfigurationUrls != null ? Util.fileNamesAsURLs(jettyConfigurationUrls, StringUtil.DEFAULT_DELIMS) : null; - - _server = configure(server, jettyConfigurations, props); - - init(); - - //if support for jsp is enabled, we need to convert locations of bundles that contain tlds into urls. - //these are tlds that we want jasper to treat as if they are on the container's classpath. Web bundles - //can use the Require-TldBundle MANIFEST header to name other tld-containing bundles that should be regarded - //as on the webapp classpath. - if (!__containerTldBundleDiscoverers.isEmpty()) - { - Set urls = new HashSet<>(); - //discover bundles with tlds that need to be on the container's classpath as URLs - for (TldBundleDiscoverer d : __containerTldBundleDiscoverers) - { - URL[] list = d.getUrlsForBundlesWithTlds(_deploymentManager, BundleFileLocatorHelperFactory.getFactory().getHelper()); - if (list != null) - { - for (URL u : list) - { - urls.add(u); - } - } - } - _commonParentClassLoaderForWebapps = new FakeURLClassLoader(libExtClassLoader, urls.toArray(new URL[urls.size()])); - } - else - _commonParentClassLoaderForWebapps = libExtClassLoader; - - if (LOG.isDebugEnabled()) - LOG.debug("common classloader = {}", _commonParentClassLoaderForWebapps); - - server.start(); - } - catch (Exception e) - { - if (server != null) - { - try - { - server.stop(); - } - catch (Exception x) - { - LOG.trace("IGNORED", x); - } - } - throw e; - } - finally - { - Thread.currentThread().setContextClassLoader(contextCl); - } - } - - public void stop() - { - try - { - if (_server.isRunning()) - { - _server.stop(); - } - } - catch (Exception e) - { - LOG.warn("Failed to stop server", e); - } - } - - /** - * Must be called after the server is configured. - * - * It is assumed the server has already been configured with the ContextHandlerCollection structure. - */ - private void init() - { - // Get the context handler - _ctxtCollection = (ContextHandlerCollection)_server.getDescendant(ContextHandlerCollection.class); - - if (_ctxtCollection == null) - throw new IllegalStateException("ERROR: No ContextHandlerCollection configured in Server"); - - List providerClassNames = new ArrayList<>(); - - // get a deployerManager and some providers - Collection deployers = _server.getBeans(DeploymentManager.class); - if (deployers != null && !deployers.isEmpty()) - { - _deploymentManager = deployers.iterator().next(); - - for (AppProvider provider : _deploymentManager.getAppProviders()) - { - providerClassNames.add(provider.getClass().getName()); - } - } - else - { - //add some kind of default - _deploymentManager = new DeploymentManager(); - _deploymentManager.setContexts(_ctxtCollection); - _server.addBean(_deploymentManager); - } - - _deploymentManager.setUseStandardBindings(false); - List deploymentLifeCycleBindings = new ArrayList<>(); - deploymentLifeCycleBindings.add(new OSGiDeployer(this)); - deploymentLifeCycleBindings.add(new StandardStarter()); - deploymentLifeCycleBindings.add(new StandardStopper()); - deploymentLifeCycleBindings.add(new OSGiUndeployer(this)); - _deploymentManager.setLifeCycleBindings(deploymentLifeCycleBindings); - - if (!providerClassNames.contains(BundleWebAppProvider.class.getName())) - { - // create it on the fly with reasonable default values. - try - { - BundleWebAppProvider webAppProvider = new BundleWebAppProvider(this); - _deploymentManager.addAppProvider(webAppProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add BundleAppProvider to DeploymentManager", e); - } - } - - if (!providerClassNames.contains(ServiceWebAppProvider.class.getName())) - { - // create it on the fly with reasonable default values. - try - { - ServiceWebAppProvider webAppProvider = new ServiceWebAppProvider(this); - _deploymentManager.addAppProvider(webAppProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add ServiceWebAppProvider to DeploymentManager", e); - } - } - - if (!providerClassNames.contains(BundleContextProvider.class.getName())) - { - try - { - BundleContextProvider contextProvider = new BundleContextProvider(this); - _deploymentManager.addAppProvider(contextProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add BundleContextProvider to DeploymentManager", e); - } - } - - if (!providerClassNames.contains(ServiceContextProvider.class.getName())) - { - try - { - ServiceContextProvider contextProvider = new ServiceContextProvider(this); - _deploymentManager.addAppProvider(contextProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add ServiceContextProvider to DeploymentManager", e); - } - } - } - - /** - * Get the Jetty Shared Lib Folder URLs in a form that is suitable for - * {@link LibExtClassLoaderHelper} to use. - * - * @param props the properties to look for the configuration in - * @return the list of URLs found, or null if none found - */ - private List getManagedJettySharedLibFolderUrls(Dictionary props) - { - String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); - if (StringUtil.isBlank(sharedURLs)) - { - return null; - } - - List libURLs = new ArrayList<>(); - - StringTokenizer tokenizer = new StringTokenizer(sharedURLs, StringUtil.DEFAULT_DELIMS, false); - while (tokenizer.hasMoreTokens()) - { - String tok = tokenizer.nextToken(); - try - { - URL url = new URL(tok); - url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(url); - if (url.getProtocol().equals("file")) - { - libURLs.add(new URL("jar:" + url.toExternalForm() + "!/")); - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("Unrecognized Jetty Shared Lib URL: {}", url); - } - } - catch (Throwable mfe) - { - LOG.warn("Unable to process legacy lib folder {}", tok, mfe); - } - } - return libURLs; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java deleted file mode 100644 index b8f9f94a29b..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/internal/webapp/LibExtClassLoaderHelper.java +++ /dev/null @@ -1,196 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.internal.webapp; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -/** - * LibExtClassLoaderHelper - *

- * Helper to create a URL class-loader with the jars inside - * ${jetty.home}/lib/ext and ${jetty.home}/resources. In an ideal world, every - * library is an OSGi bundle that does loads nicely. To support standard jars or - * bundles that cannot be loaded in the current OSGi environment, we support - * inserting the jars in the usual jetty/lib/ext folders in the proper classpath - * for the webapps. - *

- * The drawback is that those jars will not be available in the OSGi - * classloader. - *

- * Alternatives to placing jars in lib/ext: - *

    - *
  1. Bundle the jars in an osgi bundle. Have the webapp(s) that need these jars - * depend on that bundle.
  2. - *
  3. Bundle those jars in an osgi bundle-fragment that targets the - * jetty-bootstrap bundle
  4. - *
  5. Use equinox Buddy-Policy: register a buddy of the jetty bootstrapper - * bundle. (Note: it will work only on equinox)
  6. - *
- */ -public class LibExtClassLoaderHelper -{ - - /** - * IFilesInJettyHomeResourcesProcessor - * - * Interface for callback impls - */ - public interface IFilesInJettyHomeResourcesProcessor - { - void processFilesInResourcesFolder(File jettyHome, Map filesInResourcesFolder); - } - - public static final Set registeredFilesInJettyHomeResourcesProcessors = new HashSet<>(); - - /** - * @param jettyHome the jetty home - * @param parentClassLoader the parent classloader - * @return a url classloader with the jars of resources, lib/ext and the - * jars passed in the other argument. The parent classloader usually - * is the JettyBootStrapper (an osgi classloader. - * @throws MalformedURLException if the jetty home reference is invalid - */ - public static ClassLoader createLibEtcClassLoader(File jettyHome, ClassLoader parentClassLoader) throws MalformedURLException - { - if (jettyHome == null) - { - return parentClassLoader; - } - ArrayList urls = new ArrayList<>(); - File jettyResources = new File(jettyHome, "resources"); - if (jettyResources.exists()) - { - // make sure it contains something else than README: - Map jettyResFiles = new HashMap<>(); - for (File f : jettyResources.listFiles()) - { - jettyResFiles.put(f.getName(), f); - if (f.getName().toLowerCase(Locale.ENGLISH).startsWith("readme")) - { - continue; - } - else - { - if (urls.isEmpty()) - { - urls.add(jettyResources.toURI().toURL()); - } - } - } - processFilesInResourcesFolder(jettyHome, jettyResFiles); - } - File libExt = new File(jettyHome, "lib/ext"); - if (libExt.exists()) - { - for (File f : libExt.listFiles()) - { - if (FileID.isJavaArchive(f.getName())) - { - // cheap to tolerate folders so let's do it. - URL url = f.toURI().toURL(); - if (f.isFile()) - { - // is this necessary anyways? - url = new URL("jar:" + url.toString() + "!/"); - } - urls.add(url); - } - } - } - - return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader); - } - - /** - * @param jarsContainerOrJars the jars via file references - * @param otherJarsOrFolder more jars via url references - * @param parentClassLoader the parent classloader - * @return a url classloader with the jars of resources, lib/ext and the - * jars passed in the other argument. The parent classloader usually - * is the JettyBootStrapper (an osgi classloader). If there was no - * extra jars to insert, then just return the parentClassLoader. - * @throws MalformedURLException if there is a bad jar file reference - */ - public static ClassLoader createLibExtClassLoader(List jarsContainerOrJars, List otherJarsOrFolder, ClassLoader parentClassLoader) - throws MalformedURLException - { - if (jarsContainerOrJars == null && otherJarsOrFolder == null) - { - return parentClassLoader; - } - List urls = new ArrayList<>(); - if (otherJarsOrFolder != null) - { - urls.addAll(otherJarsOrFolder); - } - if (jarsContainerOrJars != null) - { - for (File libExt : jarsContainerOrJars) - { - if (libExt.isDirectory()) - { - for (File f : libExt.listFiles()) - { - if (FileID.isJavaArchive(f.getName())) - { - // cheap to tolerate folders so let's do it. - URL url = f.toURI().toURL(); - if (f.isFile()) - { - // is this necessary anyways? - url = new URL("jar:" + url.toString() + "!/"); - } - urls.add(url); - } - } - } - } - } - return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader); - } - - /** - * When we find files typically used for central logging configuration we do - * what it takes in this method to do what the user expects. Without - * depending too much directly on a particular logging framework. - *

- * We can afford to do some implementation specific code for a logging - * framework only in a fragment. - *

- * Trying to configure log4j and logback in here. - *

- * We recommend that slf4j jars are all placed in the osgi framework. And a - * single implementation if possible packaged as an osgi bundle is there. - * - * @param jettyHome the jetty home reference - * @param childrenFiles the map of child files - */ - protected static void processFilesInResourcesFolder(File jettyHome, Map childrenFiles) - { - for (IFilesInJettyHomeResourcesProcessor processor : registeredFilesInJettyHomeResourcesProcessors) - { - processor.processFilesInResourcesFolder(jettyHome, childrenFiles); - } - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelper.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelper.java deleted file mode 100644 index 25a7a22af0d..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelper.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import org.eclipse.jetty.ee10.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper; -import org.osgi.framework.Bundle; - -/** - * BundleClassLoaderHelper - *

- * Is there a clean OSGi way to go from the Bundle object to the classloader of - * the Bundle ? You can certainly take a class inside the bundle and get the - * bundle's classloader that way. Getting the classloader directly from the - * bundle would be nice. - *

- * We could use fragments that are specific to each OSGi implementation. Using - * introspection here to keep packaging simple and avoid the multiplication of - * the jars. - *

- * The default implementation relies on introspection and supports equinox-3.5 - * and felix-2.0.0 - */ -public interface BundleClassLoaderHelper -{ - - /** - * The name of the custom implementation for this interface in a fragment. - */ - public static final String CLASS_NAME = "org.eclipse.jetty.ee10.osgi.boot.utils.BundleClassLoaderHelperImpl"; - - /** - * The default instance supports felix and equinox - */ - public static BundleClassLoaderHelper DEFAULT = new DefaultBundleClassLoaderHelper(); - - /** - * @param bundle the bundle - * @return The classloader of a given bundle. Assuming the bundle is - * started. - */ - public ClassLoader getBundleClassLoader(Bundle bundle); -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelperFactory.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelperFactory.java deleted file mode 100644 index a1936b6a3a1..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleClassLoaderHelperFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * BundleClassLoaderHelperFactory - * - * Get a class loader helper adapted for the particular osgi environment. - */ -public class BundleClassLoaderHelperFactory -{ - private static final Logger LOG = LoggerFactory.getLogger(BundleClassLoaderHelperFactory.class); - - private static BundleClassLoaderHelperFactory _instance = new BundleClassLoaderHelperFactory(); - - public static BundleClassLoaderHelperFactory getFactory() - { - return _instance; - } - - private BundleClassLoaderHelperFactory() - { - } - - public BundleClassLoaderHelper getHelper() - { - //use the default - BundleClassLoaderHelper helper = BundleClassLoaderHelper.DEFAULT; - try - { - //if a fragment has not provided their own impl - helper = (BundleClassLoaderHelper)Class.forName(BundleClassLoaderHelper.CLASS_NAME) - .getDeclaredConstructor().newInstance(); - } - catch (Throwable t) - { - LOG.trace("IGNORED", t); - } - - return helper; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelper.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelper.java deleted file mode 100644 index 22ad790d438..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelper.java +++ /dev/null @@ -1,118 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import java.io.File; -import java.net.URL; -import java.util.Enumeration; - -import org.eclipse.jetty.ee10.osgi.boot.utils.internal.DefaultFileLocatorHelper; -import org.osgi.framework.Bundle; - -/** - * BundleFileLocatorHelper - *

- * From a bundle to its location on the filesystem. Assumes the bundle is not a - * jar. - */ -public interface BundleFileLocatorHelper -{ - - /** - * The name of the custom implementation for this interface in a fragment. - */ - public static final String CLASS_NAME = "org.eclipse.jetty.ee10.osgi.boot.utils.FileLocatorHelperImpl"; - - /** - * The default instance supports felix and equinox - */ - public static BundleFileLocatorHelper DEFAULT = new DefaultFileLocatorHelper(); - - /** - * Works with equinox, felix, nuxeo and probably more. Not exactly in the - * spirit of OSGi but quite necessary to support self-contained webapps and - * other situations. - *

- * Currently only works with bundles that are not jar. - * - * @param bundle The bundle - * @return Its installation location as a file. - * @throws Exception if unable to get the install location - */ - public File getBundleInstallLocation(Bundle bundle) throws Exception; - - /** - * Locate a file inside a bundle. - * - * @param bundle the bundle - * @param path the path - * @return file the file object - * @throws Exception if unable to get the file - */ - public File getFileInBundle(Bundle bundle, String path) throws Exception; - - /** - * If the bundle is a jar, returns the jar. If the bundle is a folder, look - * inside it and search for jars that it returns. - *

- * Good enough for our purpose (TldLocationsCache when it scans for tld - * files inside jars alone. In fact we only support the second situation for - * development purpose where the bundle was imported in pde and the classes - * kept in a jar. - * - * @param bundle the bundle - * @return The jar(s) file that is either the bundle itself, either the jars - * embedded inside it. - * @throws Exception if unable to locate the jars - */ - public File[] locateJarsInsideBundle(Bundle bundle) throws Exception; - - /** - * Helper method equivalent to Bundle#getEntry(String entryPath) except that - * it searches for entries in the fragments by using the findEntries method. - * - * @param bundle the bundle - * @param entryPath the entry path - * @return null or all the entries found for that path. - */ - public Enumeration findEntries(Bundle bundle, String entryPath); - - /** - * Only useful for equinox: on felix we get the file:// or jar:// url - * already. Other OSGi implementations have not been tested - *

- * Get a URL to the bundle entry that uses a common protocol (i.e. file: - * jar: or http: etc.). - * - * @param url the url - * @return a URL to the bundle entry that uses a common protocol - * @throws Exception if unable to get the local url - */ - public URL getLocalURL(URL url) throws Exception; - - /** - * Only useful for equinox: on felix we get the file:// url already. Other - * OSGi implementations have not been tested - *

- * Get a URL to the content of the bundle entry that uses the file: - * protocol. The content of the bundle entry may be downloaded or extracted - * to the local file system in order to create a file: URL. - * - * @param url the url - * @return a URL to the content of the bundle entry that uses the file: - * protocol - * @throws Exception if unable to get the file url - */ - public URL getFileURL(URL url) throws Exception; -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelperFactory.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelperFactory.java deleted file mode 100644 index 65dd438b066..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/BundleFileLocatorHelperFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * BundleFileLocatorHelperFactory - * - * Obtain a helper for locating files based on the bundle. - */ -public class BundleFileLocatorHelperFactory -{ - private static final Logger LOG = LoggerFactory.getLogger(BundleFileLocatorHelperFactory.class); - - private static BundleFileLocatorHelperFactory _instance = new BundleFileLocatorHelperFactory(); - - private BundleFileLocatorHelperFactory() - { - } - - public static BundleFileLocatorHelperFactory getFactory() - { - return _instance; - } - - public BundleFileLocatorHelper getHelper() - { - BundleFileLocatorHelper helper = BundleFileLocatorHelper.DEFAULT; - try - { - //see if a fragment has supplied an alternative - helper = (BundleFileLocatorHelper)Class.forName(BundleFileLocatorHelper.CLASS_NAME) - .getDeclaredConstructor().newInstance(); - } - catch (Throwable t) - { - LOG.trace("IGNORED", t); - } - return helper; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/EventSender.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/EventSender.java deleted file mode 100644 index 6f4bfc0d5fe..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/EventSender.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import java.util.Dictionary; -import java.util.Hashtable; - -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventAdmin; -import org.osgi.util.tracker.ServiceTracker; - -/** - * Utility class for emitting OSGi EventAdmin events - */ -public class EventSender -{ - //OSGi Event Admin events for webapps - public static final String DEPLOYING_EVENT = "org/osgi/service/web/DEPLOYING"; - public static final String DEPLOYED_EVENT = "org/osgi/service/web/DEPLOYED"; - public static final String UNDEPLOYING_EVENT = "org/osgi/service/web/UNDEPLOYING"; - public static final String UNDEPLOYED_EVENT = "org/osgi/service/web/UNDEPLOYED"; - public static final String FAILED_EVENT = "org/osgi/service/web/FAILED"; - - private static final EventSender __instance = new EventSender(); - private Bundle _myBundle; - private ServiceTracker _serviceTracker; - - private EventSender() - { - _myBundle = FrameworkUtil.getBundle(EventSender.class); - _serviceTracker = new ServiceTracker(_myBundle.getBundleContext(), EventAdmin.class.getName(), null); - _serviceTracker.open(); - } - - public static EventSender getInstance() - { - return __instance; - } - - public void send(String topic, Bundle wab, String contextPath) - { - if (topic == null || wab == null || contextPath == null) - return; - - send(topic, wab, contextPath, null); - } - - public void send(String topic, Bundle wab, String contextPath, Exception ex) - { - EventAdmin service = (EventAdmin)_serviceTracker.getService(); - if (service != null) - { - Dictionary props = new Hashtable<>(); - props.put("bundle.symbolicName", wab.getSymbolicName()); - props.put("bundle.id", wab.getBundleId()); - props.put("bundle", wab); - props.put("bundle.version", wab.getVersion()); - props.put("context.path", contextPath); - props.put("timestamp", System.currentTimeMillis()); - props.put("extender.bundle", _myBundle); - props.put("extender.bundle.symbolicName", _myBundle.getSymbolicName()); - props.put("extender.bundle.id", _myBundle.getBundleId()); - props.put("extender.bundle.version", _myBundle.getVersion()); - - if (FAILED_EVENT.equalsIgnoreCase(topic) && ex != null) - props.put("exception", ex); - - service.sendEvent(new Event(topic, props)); - } - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/FakeURLClassLoader.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/FakeURLClassLoader.java deleted file mode 100644 index f9800e1a8db..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/FakeURLClassLoader.java +++ /dev/null @@ -1,66 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import java.net.URL; -import java.net.URLClassLoader; - -/** - * FakeURLClassLoader - *

- * A URLClassloader that overrides the getURLs() method to return the list - * of urls passed in to the constructor, but otherwise acts as if it has no - * urls, which would cause it to delegate to the parent classloader (in this - * case an OSGi classloader). - *

- * The main use of this class is with jars containing tlds. Jasper expects a - * URL classloader to inspect for jars with tlds. - */ -public class FakeURLClassLoader extends URLClassLoader -{ - private URL[] _jars; - - public FakeURLClassLoader(ClassLoader osgiClassLoader, URL[] jars) - { - super(new URL[]{}, osgiClassLoader); - _jars = jars; - } - - /** - * @return the jars that contains tlds so that TldLocationsCache or - * TldScanner can find them. - */ - @Override - public URL[] getURLs() - { - return _jars; - } - - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - - if (_jars != null) - { - for (URL u : _jars) - { - builder.append(" " + u.toString()); - } - return builder.toString(); - } - else - return super.toString(); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/OSGiClassLoader.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/OSGiClassLoader.java deleted file mode 100644 index 546588d287f..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/OSGiClassLoader.java +++ /dev/null @@ -1,160 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; - -import org.osgi.framework.Bundle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * OSGiClassLoader - * - * Class loader that is aware of a bundle. Similar to WebAppClassLoader from Jetty - * and the OSGiWebAppClassLoader, but works without webapps. - */ -public class OSGiClassLoader extends URLClassLoader -{ - private static final Logger LOG = LoggerFactory.getLogger(OSGiClassLoader.class); - - private Bundle _bundle; - private ClassLoader _osgiBundleClassLoader; - private ClassLoader _parent; - - public OSGiClassLoader(ClassLoader parent, Bundle bundle) - { - super(new URL[]{}, parent); - _parent = getParent(); - _bundle = bundle; - _osgiBundleClassLoader = BundleClassLoaderHelperFactory.getFactory().getHelper().getBundleClassLoader(_bundle); - } - - /** - * Get a resource from the classloader - * - * Copied from WebAppClassLoader - */ - @Override - public URL getResource(String name) - { - URL url = null; - boolean triedParent = false; - - if (url == null) - { - url = _osgiBundleClassLoader.getResource(name); - - if (url == null && name.startsWith("/")) - { - if (LOG.isDebugEnabled()) - LOG.debug("HACK leading / off {}", name); - - url = _osgiBundleClassLoader.getResource(name.substring(1)); - } - } - - if (url == null && !triedParent) - { - if (_parent != null) - url = _parent.getResource(name); - } - - if (url != null) - if (LOG.isDebugEnabled()) - LOG.debug("getResource({})={}", name, url); - - return url; - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException - { - return loadClass(name, false); - } - - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException - { - synchronized (getClassLoadingLock(name)) - { - Class c = findLoadedClass(name); - ClassNotFoundException ex = null; - boolean triedParent = false; - - if (c == null) - { - try - { - c = this.findClass(name); - } - catch (ClassNotFoundException e) - { - ex = e; - } - } - - if (c == null && _parent != null && !triedParent) - c = _parent.loadClass(name); - - if (c == null) - throw ex; - - if (resolve) - resolveClass(c); - - if (LOG.isDebugEnabled()) - LOG.debug("loaded {} from {}", c, c.getClassLoader()); - - return c; - } - } - - @Override - public Enumeration getResources(String name) throws IOException - { - Enumeration osgiUrls = _osgiBundleClassLoader.getResources(name); - Enumeration urls = super.getResources(name); - return Collections.enumeration(toList(osgiUrls, urls)); - } - - @Override - protected Class findClass(String name) throws ClassNotFoundException - { - return _osgiBundleClassLoader.loadClass(name); - } - - /** - * - */ - private List toList(Enumeration e, Enumeration e2) - { - List list = new ArrayList<>(); - while (e != null && e.hasMoreElements()) - { - list.add(e.nextElement()); - } - while (e2 != null && e2.hasMoreElements()) - { - list.add(e2.nextElement()); - } - return list; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/ServerConnectorListener.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/ServerConnectorListener.java deleted file mode 100644 index 3d03dcb62e2..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/ServerConnectorListener.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import java.io.FileWriter; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener; -import org.eclipse.jetty.util.component.LifeCycle; - -/** - * ServerConnectorListener - * - * This is for test support, where we need jetty to run on a random port, and we need - * a client to be able to find out which port was picked. - */ -public class ServerConnectorListener extends AbstractLifeCycleListener -{ - - private Path _filePath; - private String _sysPropertyName; - - @Override - public void lifeCycleStarted(LifeCycle event) - { - if (getFilePath() != null) - { - try (FileWriter writer = new FileWriter(getFilePath().toFile())) - { - Files.deleteIfExists(_filePath); - writer.write(((ServerConnector)event).getLocalPort()); - writer.close(); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - if (getSysPropertyName() != null) - { - System.setProperty(_sysPropertyName, String.valueOf(((ServerConnector)event).getLocalPort())); - } - super.lifeCycleStarted(event); - } - - /** - * @return the filePath - */ - public Path getFilePath() - { - return _filePath; - } - - /** - * @param filePath the filePath to set - */ - public void setFilePath(Path filePath) - { - _filePath = filePath; - } - - /** - * @return the sysPropertyName - */ - public String getSysPropertyName() - { - return _sysPropertyName; - } - - /** - * @param sysPropertyName the sysPropertyName to set - */ - public void setSysPropertyName(String sysPropertyName) - { - _sysPropertyName = sysPropertyName; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/TldBundleDiscoverer.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/TldBundleDiscoverer.java deleted file mode 100644 index f0087573432..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/TldBundleDiscoverer.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import java.net.URL; - -import org.eclipse.jetty.deploy.DeploymentManager; - -/** - * TldBundleDiscoverer - * - * Convert bundles that contain tlds into URL locations for consumption by jasper. - */ -public interface TldBundleDiscoverer -{ - /** - * Find bundles that contain tlds and convert into URL references to their location. - * - * @param manager The {@link DeploymentManager} instance to use - * @param fileLocator the {@link BundleFileLocatorHelper} instance to use - * @return array of URLs representing locations of tld containing bundles - * @throws Exception In case of errors during resolving TLDs files - */ - URL[] getUrlsForBundlesWithTlds(DeploymentManager manager, BundleFileLocatorHelper fileLocator) throws Exception; -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/Util.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/Util.java deleted file mode 100644 index 2cd6a080137..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/Util.java +++ /dev/null @@ -1,166 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils; - -import java.net.URL; -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.List; -import java.util.StringTokenizer; - -import org.eclipse.jetty.ee10.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.util.StringUtil; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Filter; -import org.osgi.framework.InvalidSyntaxException; - -/** - * Various useful functions utility methods for OSGi wide use. - */ -public class Util -{ - /** - * Create an osgi filter for the given classname and server name. - * - * @param bundleContext the {@link BundleContext} instance to use - * @param classname the class to match on the filter - * @param managedServerName the name of the jetty server instance - * @return a new filter - * @throws InvalidSyntaxException If the filter contains an invalid string that cannot be parsed. - */ - public static Filter createFilter(BundleContext bundleContext, String classname, String managedServerName) throws InvalidSyntaxException - { - if (StringUtil.isBlank(managedServerName) || managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME)) - { - return bundleContext.createFilter("(&(objectclass=" + classname + ")(|(managedServerName=" + managedServerName + ")(!(managedServerName=*))))"); - } - else - { - return bundleContext.createFilter("(&(objectclass=" + classname + ")(managedServerName=" + managedServerName + "))"); - } - } - - /** - * Get the value of a manifest header. - * - * @param name the name of the header - * @param altName an alternative name for the header (useful for deprecated names) - * @param manifest the dictionary - * @return the value from the manifest - */ - public static String getManifestHeaderValue(String name, String altName, Dictionary manifest) - { - if (manifest == null) - return null; - if (name == null && altName == null) - return null; - if (name != null) - return (String)manifest.get(name); - return (String)manifest.get(altName); - } - - /** - * Get the value of a manifest header. - * - * @param name the name of the header - * @param manifest the dictionary - * @return the value from the manifest - */ - public static String getManifestHeaderValue(String name, Dictionary manifest) - { - return getManifestHeaderValue(name, null, manifest); - } - - /** - * Treating the string as a separated list of filenames, - * convert and return the list of urls. - * - * @param val the separated list of filenames - * @param delims the separators (default is ,;) - * @return the list of URLs found in the input list - * @throws Exception if unable to convert entry to a URL - */ - public static List fileNamesAsURLs(String val, String delims) - throws Exception - { - String separators = StringUtil.DEFAULT_DELIMS; - if (delims == null) - delims = separators; - - StringTokenizer tokenizer = new StringTokenizer(val, delims, false); - List urls = new ArrayList<>(); - while (tokenizer.hasMoreTokens()) - { - urls.add(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(new URL(tokenizer.nextToken()))); - } - return urls; - } - - public static void setProperty(Dictionary properties, String key, Object value) - { - if (value != null) - { - properties.put(key, value); - } - } - - /** - * recursively substitute the ${sysprop} by their actual system property. - * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no - * sysprop is defined. Not the most efficient code but we are shooting for - * simplicity and speed of development here. - * - * @param value the input string - * @return the string with replaced properties - */ - public static String resolvePropertyValue(String value) - { - int ind = value.indexOf("${"); - if (ind == -1) - { - return value; - } - int ind2 = value.indexOf('}', ind); - if (ind2 == -1) - { - return value; - } - String sysprop = value.substring(ind + 2, ind2); - String defaultValue = null; - int comma = sysprop.indexOf(','); - if (comma != -1 && comma + 1 != sysprop.length()) - { - defaultValue = sysprop.substring(comma + 1); - defaultValue = resolvePropertyValue(defaultValue); - sysprop = sysprop.substring(0, comma); - } - else - { - defaultValue = "${" + sysprop + "}"; - } - - String v = System.getProperty(sysprop); - - String reminder = value.length() > ind2 + 1 ? value.substring(ind2 + 1) : ""; - reminder = resolvePropertyValue(reminder); - if (v != null) - { - return value.substring(0, ind) + v + reminder; - } - else - { - return value.substring(0, ind) + defaultValue + reminder; - } - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java deleted file mode 100644 index f83fcb32936..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java +++ /dev/null @@ -1,428 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils.internal; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.List; - -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleClassLoaderHelper; -import org.osgi.framework.Bundle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * DefaultBundleClassLoaderHelper - *

- * Default implementation of the BundleClassLoaderHelper. Uses introspection to - * support equinox-3.5 and felix-2.0.0 - */ -public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper -{ - private static final Logger LOG = LoggerFactory.getLogger(BundleClassLoaderHelper.class); - - private static enum OSGiContainerType - { - EquinoxOld, EquinoxLuna, FelixOld, Felix403, Concierge - } - - ; - private static OSGiContainerType osgiContainer; - private static Class Equinox_BundleHost_Class; - private static Class Equinox_EquinoxBundle_Class; - private static Class Felix_BundleImpl_Class; - private static Class Felix_BundleWiring_Class; - //old equinox - private static Method Equinox_BundleHost_getBundleLoader_method; - private static Method Equinox_BundleLoader_createClassLoader_method; - //new equinox - private static Method Equinox_EquinoxBundle_getModuleClassLoader_Method; - - //new felix - private static Method Felix_BundleImpl_Adapt_Method; - //old felix - private static Field Felix_BundleImpl_m_Modules_Field; - private static Field Felix_ModuleImpl_m_ClassLoader_Field; - private static Method Felix_BundleWiring_getClassLoader_Method; - - // Concierge - private static Class Concierge_BundleImpl_Class; - private static Class Concierge_BundleWiring_Class; - private static Method Concierge_BundleImpl_Adapt_Method; - private static Method Concierge_BundleWiring_getClassLoader_Method; - - private static void checkContainerType(Bundle bundle) - { - if (osgiContainer != null) - return; - - try - { - Equinox_BundleHost_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost"); - osgiContainer = OSGiContainerType.EquinoxOld; - return; - } - catch (ClassNotFoundException e) - { - LOG.trace("IGNORED", e); - } - - try - { - Equinox_EquinoxBundle_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.framework.EquinoxBundle"); - osgiContainer = OSGiContainerType.EquinoxLuna; - return; - } - catch (ClassNotFoundException e) - { - LOG.trace("IGNORED", e); - } - - try - { - //old felix or new felix? - Felix_BundleImpl_Class = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl"); - try - { - Felix_BundleImpl_Adapt_Method = Felix_BundleImpl_Class.getDeclaredMethod("adapt", new Class[]{Class.class}); - osgiContainer = OSGiContainerType.Felix403; - return; - } - catch (NoSuchMethodException e) - { - osgiContainer = OSGiContainerType.FelixOld; - return; - } - } - catch (ClassNotFoundException e) - { - LOG.trace("IGNORED", e); - } - - try - { - Concierge_BundleImpl_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.concierge.BundleImpl"); - osgiContainer = OSGiContainerType.Concierge; - return; - } - catch (ClassNotFoundException e) - { - LOG.trace("IGNORED", e); - } - - LOG.warn("Unknown OSGi container type"); - return; - } - - /** - * Assuming the bundle is started. - * - * @param bundle the bundle - * @return classloader object - */ - @Override - public ClassLoader getBundleClassLoader(Bundle bundle) - { - String bundleActivator = (String)bundle.getHeaders().get("Bundle-Activator"); - - if (bundleActivator == null) - { - bundleActivator = (String)bundle.getHeaders().get("Jetty-ClassInBundle"); - } - if (bundleActivator != null) - { - try - { - return bundle.loadClass(bundleActivator).getClassLoader(); - } - catch (ClassNotFoundException e) - { - LOG.warn("Unable to load bundle activator {}", bundleActivator, e); - } - } - - // resort to introspection - return getBundleClassLoaderForContainer(bundle); - } - - /** - * - */ - private ClassLoader getBundleClassLoaderForContainer(Bundle bundle) - { - checkContainerType(bundle); - if (osgiContainer == null) - { - LOG.warn("No classloader for unknown OSGi container type"); - return null; - } - - switch (osgiContainer) - { - case EquinoxOld: - case EquinoxLuna: - { - return internalGetEquinoxBundleClassLoader(bundle); - } - - case FelixOld: - case Felix403: - { - return internalGetFelixBundleClassLoader(bundle); - } - - case Concierge: - { - return internalGetConciergeBundleClassLoader(bundle); - } - - default: - { - LOG.warn("No classloader found for bundle {}", bundle.getSymbolicName()); - return null; - } - } - } - - /** - * - */ - private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle) - { - if (osgiContainer == OSGiContainerType.EquinoxOld) - { - String bundleLoaderName = "org.eclipse.osgi.internal.loader.BundleLoader"; - try - { - if (Equinox_BundleHost_getBundleLoader_method == null) - { - Equinox_BundleHost_getBundleLoader_method = - Equinox_BundleHost_Class.getDeclaredMethod("getBundleLoader", new Class[]{}); - Equinox_BundleHost_getBundleLoader_method.setAccessible(true); - } - Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle, new Object[]{}); - if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null) - { - Equinox_BundleLoader_createClassLoader_method = - bundleLoader.getClass().getClassLoader().loadClass(bundleLoaderName).getDeclaredMethod("createClassLoader", new Class[]{}); - Equinox_BundleLoader_createClassLoader_method.setAccessible(true); - } - return (ClassLoader)Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[]{}); - } - catch (Throwable t) - { - LOG.warn("Unable to get equinox bundle classloader", t); - return null; - } - } - - if (osgiContainer == OSGiContainerType.EquinoxLuna) - { - try - { - if (Equinox_EquinoxBundle_getModuleClassLoader_Method == null) - Equinox_EquinoxBundle_getModuleClassLoader_Method = Equinox_EquinoxBundle_Class.getDeclaredMethod("getModuleClassLoader", new Class[]{ - Boolean.TYPE - }); - - Equinox_EquinoxBundle_getModuleClassLoader_Method.setAccessible(true); - return (ClassLoader)Equinox_EquinoxBundle_getModuleClassLoader_Method.invoke(bundle, new Object[]{ - Boolean.FALSE - }); - } - catch (Exception e) - { - LOG.warn("Unable to get equinox luna bundle classloader", e); - return null; - } - } - - LOG.warn("No classloader for equinox platform for bundle {}", bundle.getSymbolicName()); - return null; - } - - /** - * - */ - @SuppressWarnings("unchecked") - private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle) - { - - if (osgiContainer == OSGiContainerType.Felix403) - { - try - { - if (Felix_BundleWiring_Class == null) - Felix_BundleWiring_Class = bundle.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring"); - - Felix_BundleImpl_Adapt_Method.setAccessible(true); - - if (Felix_BundleWiring_getClassLoader_Method == null) - { - Felix_BundleWiring_getClassLoader_Method = Felix_BundleWiring_Class.getDeclaredMethod("getClassLoader"); - Felix_BundleWiring_getClassLoader_Method.setAccessible(true); - } - - Object wiring = Felix_BundleImpl_Adapt_Method.invoke(bundle, new Object[]{Felix_BundleWiring_Class}); - return (ClassLoader)Felix_BundleWiring_getClassLoader_Method.invoke(wiring); - } - catch (Exception e) - { - LOG.warn("Unable to get felix bundle classloader", e); - return null; - } - } - - if (osgiContainer == OSGiContainerType.FelixOld) - { - try - { - if (Felix_BundleImpl_m_Modules_Field == null) - { - Felix_BundleImpl_m_Modules_Field = Felix_BundleImpl_Class.getDeclaredField("m_modules"); - Felix_BundleImpl_m_Modules_Field.setAccessible(true); - } - - // Figure out which version of the modules is exported - Object currentModuleImpl; - - try - { - Object[] moduleArray = (Object[])Felix_BundleImpl_m_Modules_Field.get(bundle); - currentModuleImpl = moduleArray[moduleArray.length - 1]; - } - catch (Throwable ex) - { - try - { - List moduleArray = (List)Felix_BundleImpl_m_Modules_Field.get(bundle); - currentModuleImpl = moduleArray.get(moduleArray.size() - 1); - } - catch (Exception e) - { - LOG.warn("Unable to get field {}", Felix_BundleImpl_m_Modules_Field, e); - return null; - } - } - - if (Felix_ModuleImpl_m_ClassLoader_Field == null && currentModuleImpl != null) - { - String felixFrameworkModuleImplClassName = "org.apache.felix.framework.ModuleImpl"; - String felixFrameworkModuleImplClassLoaderField = "m_classLoader"; - try - { - Felix_ModuleImpl_m_ClassLoader_Field = bundle.getClass().getClassLoader().loadClass(felixFrameworkModuleImplClassName).getDeclaredField(felixFrameworkModuleImplClassLoaderField); - Felix_ModuleImpl_m_ClassLoader_Field.setAccessible(true); - } - catch (Exception e) - { - LOG.warn("Unable to find field {}.{}", felixFrameworkModuleImplClassName, felixFrameworkModuleImplClassLoaderField, e); - return null; - } - } - - // first make sure that the classloader is ready: - // the m_classLoader field must be initialized by the - // ModuleImpl.getClassLoader() private method. - ClassLoader cl = null; - try - { - cl = (ClassLoader)Felix_ModuleImpl_m_ClassLoader_Field.get(currentModuleImpl); - if (cl != null) - return cl; - } - catch (Exception e) - { - LOG.warn("Unable to get field {}", Felix_ModuleImpl_m_ClassLoader_Field, e); - return null; - } - - // looks like it was not ready: - // the m_classLoader field must be initialized by the - // ModuleImpl.getClassLoader() private method. - // this call will do that. - try - { - bundle.loadClass("java.lang.Object"); - cl = (ClassLoader)Felix_ModuleImpl_m_ClassLoader_Field.get(currentModuleImpl); - return cl; - } - catch (Exception e) - { - LOG.warn("Unable to get field {}", Felix_ModuleImpl_m_ClassLoader_Field, e); - return null; - } - } - catch (Exception e) - { - LOG.warn("Unable to load old felix container", e); - return null; - } - } - - LOG.warn("No classloader for felix platform for bundle {}", bundle.getSymbolicName()); - return null; - } - - /** - * - */ - private static ClassLoader internalGetConciergeBundleClassLoader(Bundle bundle) - { - if (osgiContainer == OSGiContainerType.Concierge) - { - try - { - /** - * In Concierge: - * - * Option A: - *
-                 * Concierge concierge = new Concierge(...);
-                 * BundleWiring bundleWiring = concierge.getWiring(); // method is public
-                 * 
- * Problem: getWiring not yet implementd - * - * Option B: - *
-                 * Concierge concierge = new Concierge(...);
-                 * BundleWiring bundleWiring = concierge.adapt(org.osgi.framework.wiring.BundleWiring);
-                 * 
- * Same approach as done in Felix. - * - */ - if (Concierge_BundleWiring_Class == null) - { - Concierge_BundleWiring_Class = bundle.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring"); - Concierge_BundleImpl_Adapt_Method = Concierge_BundleImpl_Class.getMethod("adapt", new Class[]{Class.class}); - Concierge_BundleImpl_Adapt_Method.setAccessible(true); - Concierge_BundleWiring_getClassLoader_Method = Concierge_BundleWiring_Class.getMethod("getClassLoader"); - Concierge_BundleWiring_getClassLoader_Method.setAccessible(true); - } - - Object wiring = Concierge_BundleImpl_Adapt_Method.invoke(bundle, new Object[]{Concierge_BundleWiring_Class}); - ClassLoader cl = (ClassLoader)Concierge_BundleWiring_getClassLoader_Method.invoke(wiring); - return cl; - } - catch (Exception e) - { - LOG.warn("Unable to load Concierge platform", e); - return null; - } - } - - LOG.warn("No classloader for Concierge platform for bundle {}", bundle.getSymbolicName()); - return null; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultFileLocatorHelper.java deleted file mode 100644 index 37865c3764a..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/utils/internal/DefaultFileLocatorHelper.java +++ /dev/null @@ -1,385 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.boot.utils.internal; - -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.zip.ZipFile; - -import org.eclipse.jetty.ee10.osgi.boot.utils.BundleFileLocatorHelper; -import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.resource.PathResource; -import org.eclipse.jetty.util.resource.Resource; -import org.osgi.framework.Bundle; - -/** - * DefaultFileLocatorHelper - *

- * From a bundle to its location on the filesystem. Assumes the bundle is not a - * jar. - */ -public class DefaultFileLocatorHelper implements BundleFileLocatorHelper -{ - - // hack to locate the file-system directly from the bundle. - // support equinox, felix and nuxeo's osgi implementations. - // not tested on nuxeo and felix just yet. - // The url nuxeo and felix return is created directly from the File so it - // should work. - private static Field BUNDLE_ENTRY_FIELD = null; - - private static Field FILE_FIELD = null; - - private static Field BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = null; // ZipBundleFile - - // inside - // DirZipBundleEntry - - private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null; // ZipFile - - private static final String[] FILE_BUNDLE_ENTRY_CLASSES = { - "org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry", "org.eclipse.osgi.storage.bundlefile.FileBundleEntry" - }; - private static final String[] ZIP_BUNDLE_ENTRY_CLASSES = { - "org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry", "org.eclipse.osgi.storage.bundlefile.ZipBundleEntry" - }; - private static final String[] DIR_ZIP_BUNDLE_ENTRY_CLASSES = { - "org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry", "org.eclipse.osgi.storage.bundlefile.DirZipBundleEntry" - }; - private static final String[] BUNDLE_URL_CONNECTION_CLASSES = { - "org.eclipse.osgi.framework.internal.core.BundleURLConnection", "org.eclipse.osgi.storage.url.BundleURLConnection" - }; - - public static boolean match(String name, String... names) - { - if (name == null || names == null) - return false; - boolean matched = false; - for (int i = 0; i < names.length && !matched; i++) - { - if (name.equals(names[i])) - matched = true; - } - return matched; - } - - /** - * Works with equinox, felix, nuxeo and probably more. Not exactly in the - * spirit of OSGi but quite necessary to support self-contained webapps and - * other situations. - * - * @param bundle The bundle - * @return Its installation location as a file. - * @throws Exception if unable to get the bundle install location - */ - @SuppressWarnings("resource") - public File getBundleInstallLocation(Bundle bundle) throws Exception - { - // String installedBundles = System.getProperty("osgi.bundles"); - // grab the MANIFEST.MF's url - // and then do what it takes. - URL url = bundle.getEntry("/META-INF/MANIFEST.MF"); - - if (url.getProtocol().equals("file")) - { - // some osgi frameworks do use the file protocol directly in some - // situations. Do use the PathResource to transform the URL into a - // File: URL#toURI is broken - return new PathResource(url).getFile().getParentFile().getParentFile().getCanonicalFile(); - } - else if (url.getProtocol().equals("bundleentry")) - { - // say hello to equinox who has its own protocol. - // we use introspection like there is no tomorrow to get access to - // the File - - URLConnection con = url.openConnection(); - con.setUseCaches(Resource.getDefaultUseCaches()); // work around - // problems where - // url connections - // cache - // references to - // jars - - if (BUNDLE_ENTRY_FIELD == null) - { - BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry"); - BUNDLE_ENTRY_FIELD.setAccessible(true); - } - Object bundleEntry = BUNDLE_ENTRY_FIELD.get(con); - - if (match(bundleEntry.getClass().getName(), FILE_BUNDLE_ENTRY_CLASSES)) - { - if (FILE_FIELD == null) - { - FILE_FIELD = bundleEntry.getClass().getDeclaredField("file"); - FILE_FIELD.setAccessible(true); - } - File f = (File)FILE_FIELD.get(bundleEntry); - return f.getParentFile().getParentFile().getCanonicalFile(); - } - else if (match(bundleEntry.getClass().getName(), ZIP_BUNDLE_ENTRY_CLASSES)) - { - url = bundle.getEntry("/"); - - con = url.openConnection(); - con.setDefaultUseCaches(Resource.getDefaultUseCaches()); - - if (BUNDLE_ENTRY_FIELD == null) - { - // this one will be a DirZipBundleEntry - BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry"); - BUNDLE_ENTRY_FIELD.setAccessible(true); - } - bundleEntry = BUNDLE_ENTRY_FIELD.get(con); - if (BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY == null) - { - BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = bundleEntry.getClass().getDeclaredField("bundleFile"); - BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.setAccessible(true); - } - Object zipBundleFile = BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.get(bundleEntry); - if (ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE == null) - { - ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = zipBundleFile.getClass().getDeclaredField("zipFile"); - ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.setAccessible(true); - } - ZipFile zipFile = (ZipFile)ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile); - return new File(zipFile.getName()); - } - else if (match(bundleEntry.getClass().getName(), DIR_ZIP_BUNDLE_ENTRY_CLASSES)) - { - // that will not happen as we did ask for the manifest not a - // directory. - } - } - else if ("bundle".equals(url.getProtocol())) - { - // observed this on felix-2.0.0 - String location = bundle.getLocation(); - if (location.startsWith("file:/")) - { - URI uri = new URI(URIUtil.encodePath(location)); - return new File(uri).getCanonicalFile(); - } - else if (location.startsWith("file:")) - { - // location defined in the BundleArchive m_bundleArchive - // it is relative to relative to the BundleArchive's - // m_archiveRootDir - File res = new File(location.substring("file:".length())); - if (!res.exists()) - { - return null; - // Object bundleArchive = getFelixBundleArchive(bundle); - // File archiveRoot = - // getFelixBundleArchiveRootDir(bundleArchive); - // String currentLocation = - // getFelixBundleArchiveCurrentLocation(bundleArchive); - // System.err.println("Got the archive root " + - // archiveRoot.getAbsolutePath() - // + " current location " + currentLocation + - // " is directory ?"); - // res = new File(archiveRoot, currentLocation != null - // ? currentLocation : location.substring("file:".length())); - } - return res; - } - else if (location.startsWith("reference:file:")) - { - location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8"); - File file = new File(location.substring("file:".length())).getCanonicalFile(); - return file; - } - } - return null; - } - - /** - * Locate a file inside a bundle. - * - * @param bundle the bundle - * @param path the path - * @return file object - * @throws Exception if unable to get the file in the bundle - */ - @Override - public File getFileInBundle(Bundle bundle, String path) throws Exception - { - if (path != null && path.length() > 0 && path.charAt(0) == '/') - { - path = path.substring(1); - } - File bundleInstall = getBundleInstallLocation(bundle); - File webapp = path != null && path.length() != 0 ? new File(bundleInstall, path) : bundleInstall; - if (!webapp.exists()) - { - throw new IllegalArgumentException("Unable to locate " + path + " inside " + bundle.getSymbolicName() + - " (" + (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ") + ")"); - } - return webapp; - } - - /** - * Helper method equivalent to Bundle#getEntry(String entryPath) except that - * it searches for entries in the fragments by using the Bundle#findEntries - * method. - * - * @param bundle the bundle - * @param entryPath the entry path - * @return null or all the entries found for that path. - */ - @Override - public Enumeration findEntries(Bundle bundle, String entryPath) - { - int last = entryPath.lastIndexOf('/'); - String path = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(0, last) : "/"; - if (!path.startsWith("/")) - { - path = "/" + path; - } - String pattern = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(last + 1) : entryPath; - @SuppressWarnings("unchecked") - Enumeration enUrls = bundle.findEntries(path, pattern, false); - return enUrls; - } - - /** - * If the bundle is a jar, returns the jar. If the bundle is a folder, look - * inside it and search for jars that it returns. - *

- * Good enough for our purpose (TldLocationsCache when it scans for tld - * files inside jars alone. In fact we only support the second situation for - * development purpose where the bundle was imported in pde and the classes - * kept in a jar. - *

- * - * @param bundle the bundle - * @return The jar(s) file that is either the bundle itself, either the jars - * embedded inside it. - */ - @Override - public File[] locateJarsInsideBundle(Bundle bundle) throws Exception - { - File jasperLocation = getBundleInstallLocation(bundle); - if (jasperLocation.isDirectory()) - { - // try to find the jar files inside this folder - ArrayList urls = new ArrayList<>(); - for (File f : jasperLocation.listFiles()) - { - if (FileID.isJavaArchive(f.getName()) && f.isFile()) - { - urls.add(f); - } - else if (f.isDirectory() && f.getName().equals("lib")) - { - for (File f2 : jasperLocation.listFiles()) - { - if (FileID.isJavaArchive(f2.getName()) && f2.isFile()) - { - urls.add(f2); - } - } - } - } - return urls.toArray(new File[urls.size()]); - } - else - { - return new File[]{jasperLocation}; - } - } - - // introspection on equinox to invoke the getLocalURL method on - // BundleURLConnection - // equivalent to using the FileLocator without depending on an equinox - // class. - private static Method BUNDLE_URL_CONNECTION_getLocalURL = null; - - private static Method BUNDLE_URL_CONNECTION_getFileURL = null; - - /** - * Only useful for equinox: on felix we get the file:// or jar:// url - * already. Other OSGi implementations have not been tested - *

- * Get a URL to the bundle entry that uses a common protocol (i.e. file: - * jar: or http: etc.). - *

- * - * @return a URL to the bundle entry that uses a common protocol - */ - @Override - public URL getLocalURL(URL url) - throws Exception - { - if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) - { - - URLConnection conn = url.openConnection(); - conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); - if (BUNDLE_URL_CONNECTION_getLocalURL == null && match(conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES)) - { - BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL"); - BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true); - } - if (BUNDLE_URL_CONNECTION_getLocalURL != null) - { - return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn); - } - } - return url; - } - - /** - * Only useful for equinox: on felix we get the file:// url already. Other - * OSGi implementations have not been tested - *

- * Get a URL to the content of the bundle entry that uses the file: - * protocol. The content of the bundle entry may be downloaded or extracted - * to the local file system in order to create a file: URL. - *

- * - * @return a URL to the content of the bundle entry that uses the file: - * protocol - * @throws Exception if unable to get the file url - */ - @Override - public URL getFileURL(URL url) throws Exception - - { - if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol())) - { - - URLConnection conn = url.openConnection(); - conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); - if (BUNDLE_URL_CONNECTION_getFileURL == null && match(conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES)) - { - BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL"); - BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true); - } - if (BUNDLE_URL_CONNECTION_getFileURL != null) - { - return (URL)BUNDLE_URL_CONNECTION_getFileURL.invoke(conn); - } - } - return url; - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.webapp.Configuration b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.webapp.Configuration index a9508c57a3d..0fce4bff25b 100644 --- a/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.webapp.Configuration +++ b/jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.webapp.Configuration @@ -1,2 +1,2 @@ org.eclipse.jetty.ee10.osgi.annotations.AnnotationConfiguration -org.eclipse.jetty.ee10.osgi.boot.OSGiWebInfConfiguration +org.eclipse.jetty.ee10.osgi.boot.OSGiMetaInfConfiguration diff --git a/jetty-ee10/jetty-ee10-osgi/pom.xml b/jetty-ee10/jetty-ee10-osgi/pom.xml index 090b763bf92..906a2deefe2 100644 --- a/jetty-ee10/jetty-ee10-osgi/pom.xml +++ b/jetty-ee10/jetty-ee10-osgi/pom.xml @@ -12,23 +12,30 @@ pom - 3.17.200 - 3.10.200 - 3.6.100 + 3.18.100 + 8.1.0 + 3.11.0 + 1.6.1 + 1.5.0 + 1.4.1 + 3.7.100 + 1.2.0 + 1.2.0 + 1.0.2 + 1.0.1 + 1.5.4 + 1.0.2 1.0.0-v20070606 true + jetty-ee10-osgi-alpn jetty-ee10-osgi-boot jetty-ee10-osgi-boot-jsp - jetty-ee10-osgi-boot-warurl - test-jetty-ee10-osgi-webapp test-jetty-ee10-osgi-webapp-resources - test-jetty-ee10-osgi-context test-jetty-ee10-osgi-fragment test-jetty-ee10-osgi-server - jetty-ee10-osgi-alpn test-jetty-ee10-osgi @@ -60,24 +67,6 @@ - - - org.codehaus.mojo - build-helper-maven-plugin - - - set-servlet-api-version - validate - - parse-version - - - ${jetty.servlet.api.version} - servletImpl - - - - org.apache.maven.plugins maven-eclipse-plugin @@ -117,11 +106,36 @@ org.eclipse.osgi ${osgi-version} + + org.osgi + org.osgi.service.cm + ${osgi-service-cm-version} + + + org.osgi + org.osgi.service.component + ${osgi-service-component-version} + + + org.osgi + org.osgi.service.event + ${osgi-service-event-version} + + + org.osgi + org.osgi.util.tracker + ${osgi-util-tracker-version} + org.eclipse.equinox.http servlet ${equinox-http-servlet-version} + + org.osgi + osgi.annotation + ${osgi-annotation-version} + diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/pom.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/pom.xml deleted file mode 100644 index 1e29f84ff9f..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/pom.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - org.eclipse.jetty.ee10.osgi - jetty-ee10-osgi-project - 12.0.0-SNAPSHOT - - 4.0.0 - test-jetty-ee10-osgi-context - EE10 :: Jetty :: OSGi :: Test Context - Test Jetty OSGi bundle with a ContextHandler - - ${project.groupId}.testcontext - true - true - - - - org.eclipse.jetty - jetty-server - - - jakarta.servlet - jakarta.servlet-api - - - org.eclipse.platform - org.eclipse.osgi - provided - - - org.eclipse.platform - org.eclipse.osgi.services - provided - - - - - - - src/main/resources - - - src/main/context - - - - - org.apache.felix - maven-bundle-plugin - true - - - org.eclipse.jetty.ee10.osgi.testcontext;singleton:=true - Jetty OSGi Test Context - com.acme.osgi.Activator - J2SE-1.5 - - <_nouses>true - - jakarta.servlet;version="[$(version;==;${servletImpl.osgiVersion}),$(version;+;${servletImpl.osgiVersion}))", - jakarta.servlet.resources;version="[$(version;==;${servletImpl.osgiVersion}),$(version;+;${servletImpl.osgiVersion}))", - org.osgi.framework, - org.osgi.service.cm;version="1.2.0", - org.osgi.service.packageadmin, - org.osgi.service.startlevel;version="1.0.0", - org.osgi.service.url;version="1.0.0", - org.osgi.util.tracker;version="1.3.0", - * - - org.eclipse.jetty.*;version="[$(version;==;${parsedVersion.osgiVersion}),$(version;+;${parsedVersion.osgiVersion}))" - - - - - - - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/context/acme.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/context/acme.xml deleted file mode 100644 index e6221cb3cb0..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/context/acme.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - /unset - - - /static/ - - - - - - index.html - - - max-age=3600,public - - - - - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/java/com/acme/osgi/Activator.java b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/java/com/acme/osgi/Activator.java deleted file mode 100644 index 6639fd4211d..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/java/com/acme/osgi/Activator.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package com.acme.osgi; - -import java.util.Dictionary; -import java.util.Hashtable; - -import jakarta.servlet.ServletContextEvent; -import jakarta.servlet.ServletContextListener; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -/** - * Bootstrap a ContextHandler - */ -public class Activator implements BundleActivator -{ - - private ServiceRegistration _sr; - - /** - * - */ - @Override - public void start(final BundleContext context) throws Exception - { - ContextHandler ch = new ContextHandler(); - ch.addEventListener(new ServletContextListener() - { - - @Override - public void contextInitialized(ServletContextEvent sce) - { - //System.err.println("Context is initialized"); - } - - @Override - public void contextDestroyed(ServletContextEvent sce) - { - //System.err.println("CONTEXT IS DESTROYED!"); - } - }); - Dictionary props = new Hashtable(); - props.put("Web-ContextPath", "/acme"); - props.put("Jetty-ContextFilePath", "acme.xml"); - _sr = context.registerService(ContextHandler.class.getName(), ch, props); - } - - /** - * Stop the activator. - * - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception - { - _sr.unregister(); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/resources/static/index.html b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/resources/static/index.html deleted file mode 100644 index 3189646adce..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-context/src/main/resources/static/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi Context

-

ContextHandler registered as a service successfully deployed.

- - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-server/pom.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-server/pom.xml index c956c0573b6..a2af825a8c5 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-server/pom.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-server/pom.xml @@ -57,7 +57,7 @@ org.xml.sax.helpers, * - org.eclipse.jetty.*;version="[$(version;==;${parsedVersion.osgiVersion}),$(version;+;${parsedVersion.osgiVersion}))" + org.eclipse.jetty.*;version="[$(version;==;${parsedVersion.osgiVersion}),$(version;+;${parsedVersion.osgiVersion}))", org.eclipse.jetty.ee10.*;version="[$(version;==;${parsedVersion.osgiVersion}),$(version;+;${parsedVersion.osgiVersion}))"
diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp-resources/pom.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp-resources/pom.xml index 756467225c5..11760d49333 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp-resources/pom.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp-resources/pom.xml @@ -47,7 +47,8 @@ !com.acme* - / + /test-webapp-resources + ee10 diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/pom.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/pom.xml deleted file mode 100644 index 9e536073353..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - org.eclipse.jetty.ee10.osgi - jetty-ee10-osgi-project - 12.0.0-SNAPSHOT - ../pom.xml - - 4.0.0 - test-jetty-ee10-osgi-webapp - EE10 :: Jetty :: OSGi :: Test WebApp - Test Jetty OSGi Webapp bundle - - ${project.groupId}.webapp - true - true - - - - org.eclipse.jetty.ee10 - jetty-ee10-webapp - - - org.eclipse.platform - org.eclipse.osgi - provided - - - org.eclipse.platform - org.eclipse.osgi.services - provided - - - - - - - src/main/resources - - - - - org.apache.felix - maven-bundle-plugin - true - - - org.eclipse.jetty.ee10.osgi.testapp;singleton:=true - Jetty OSGi Test WebApp - com.acme.osgi.Activator - J2SE-1.5 - - com.acme.osgi - org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))" - - - - - - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/java/com/acme/osgi/Activator.java b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/java/com/acme/osgi/Activator.java deleted file mode 100644 index 5f1e532f083..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/java/com/acme/osgi/Activator.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package com.acme.osgi; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Dictionary; -import java.util.Hashtable; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee10.servlet.ServletHolder; -import org.eclipse.jetty.ee10.webapp.WebAppContext; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -/** - * Bootstrap a webapp - */ -public class Activator implements BundleActivator -{ - - private ServiceRegistration _srA; - private ServiceRegistration _srB; - - public static class TestServlet extends HttpServlet - { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - //report the mimetype of a file - String mimetype = req.getServletContext().getMimeType("file.gz"); - resp.setContentType("text/html"); - PrintWriter writer = resp.getWriter(); - writer.write("

MIMETYPE=" + mimetype + "

"); - writer.flush(); - } - } - - /** - * - */ - @Override - public void start(BundleContext context) throws Exception - { - //Create webappA as a Service and target it at the default server - WebAppContext webapp = new WebAppContext(); - webapp.addServlet(new ServletHolder(new TestServlet()), "/mime"); - Dictionary props = new Hashtable(); - props.put("Jetty-WarResourcePath", "webappA"); - props.put("Web-ContextPath", "/acme"); - props.put("managedServerName", "defaultJettyServer"); - _srA = context.registerService(WebAppContext.class.getName(), webapp, props); - - //Create a second webappB as a Service and target it at a custom Server - //deployed by another bundle - final WebAppContext webappB = new WebAppContext(); - Dictionary propsB = new Hashtable(); - propsB.put("Jetty-WarResourcePath", "webappB"); - propsB.put("Web-ContextPath", "/acme"); - propsB.put("managedServerName", "fooServer"); - _srB = context.registerService(WebAppContext.class.getName(), webappB, propsB); - } - - /** - * Stop the activator. - * - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception - { - _srA.unregister(); - _srB.unregister(); - } -} diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/index.html b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/index.html deleted file mode 100644 index 9e62c04bb91..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi WebApp

-

Webapp registered by bundle as service successfully deployed.

- - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappA/index.html b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappA/index.html deleted file mode 100644 index bc4c64faa54..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappA/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi WebAppA

-

Webapp registered by bundle as service successfully deployed.

- - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappB/index.html b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappB/index.html deleted file mode 100644 index 4c6a3ae9b22..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp/src/main/resources/webappB/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi WebAppB

-

Webapp registered by bundle as service successfully deployed.

- - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/pom.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/pom.xml index ef3818991bc..a8d82b27b4c 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/pom.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/pom.xml @@ -17,9 +17,8 @@ 2.6.2 1.8.3 3.0.0 - 1.3.4 - - true + 1.3.6 + 1.2 true @@ -138,17 +137,43 @@ 1.2 test + + org.osgi + org.osgi.util.promise + ${osgi-util-promise-version} + test + + + org.osgi + org.osgi.util.measurement + ${osgi-util-measurement-version} + test + + + org.osgi + org.osgi.util.position + ${osgi-util-position-version} + test + + + org.osgi + org.osgi.util.xml + ${osgi-util-xml-version} + test + org.slf4j slf4j-api test + org.eclipse.jetty jetty-slf4j-impl @@ -187,8 +212,8 @@ - jakarta.servlet - jakarta.servlet-api + jakarta.servlet + jakarta.servlet-api jakarta.inject @@ -255,6 +280,11 @@ jakarta.servlet.jsp.jstl + + org.eclipse.jetty.ee10 + jetty-ee10-jndi + runtime + org.eclipse.jetty.ee10 jetty-ee10-annotations @@ -306,32 +336,32 @@ runtime - org.eclipse.jetty.ee10 + org.eclipse.jetty.ee10.websocket jetty-ee10-websocket-jetty-api runtime - org.eclipse.jetty.ee10 + org.eclipse.jetty.ee10.websocket jetty-ee10-websocket-jetty-common runtime - org.eclipse.jetty.ee10 + org.eclipse.jetty.ee10.websocket jetty-ee10-websocket-jetty-client runtime - org.eclipse.jetty.ee10 + org.eclipse.jetty.ee10.websocket jetty-ee10-websocket-jakarta-client runtime - org.eclipse.jetty.ee10 + org.eclipse.jetty.ee10.websocket jetty-ee10-websocket-servlet runtime - org.eclipse.jetty.ee10 + org.eclipse.jetty.ee10.websocket jetty-ee10-websocket-jetty-server runtime @@ -341,7 +371,7 @@ runtime - org.eclipse.jetty.ee10 + org.eclipse.jetty.ee10.websocket jetty-ee10-websocket-jakarta-server runtime @@ -353,12 +383,6 @@ org.eclipse.jetty.http2 jetty-http2-hpack - - org.eclipse.jetty.ee10.osgi - jetty-ee10-osgi-alpn - ${project.version} - test - org.eclipse.jetty jetty-alpn-server @@ -370,32 +394,38 @@ jetty-ee10-plus runtime + + org.eclipse.jetty.ee10.osgi + jetty-ee10-osgi-alpn + ${project.version} + test + org.eclipse.jetty.ee10.demos - demo-jsp-webapp + jetty-ee10-demo-jsp-webapp ${project.version} webbundle test org.eclipse.jetty.ee10.demos - demo-jetty-webapp + jetty-ee10-demo-jetty-webapp ${project.version} webbundle test org.eclipse.jetty.ee10.demos - demo-spec-webapp + jetty-ee10-demo-spec-webapp ${project.version} war test org.eclipse.jetty.ee10.demos - demo-container-initializer + jetty-ee10-demo-container-initializer ${project.version} test @@ -420,21 +450,9 @@ org.eclipse.jetty.ee10.demos - demo-mock-resources + jetty-ee10-demo-mock-resources ${project.version} - - org.eclipse.jetty.ee10.osgi - test-jetty-ee10-osgi-context - ${project.version} - test - - - org.eclipse.jetty.ee10.osgi - test-jetty-ee10-osgi-webapp - ${project.version} - test - org.eclipse.jetty.toolchain jetty-test-helper @@ -525,6 +543,12 @@ ${env.GLOBAL_MVN_SETTINGS} -Dconscrypt-version=${conscrypt.version} + + + **/TestJettyOSGiBootHTTP2Conscrypt.java + **/TestJettyOSGiBootHTTP2JDK9.java + **/TestJettyOSGiBootWithJakartaWebSocket.java + diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-deploy.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-deploy.xml index fe917c2430e..e630c9a766e 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-deploy.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-deploy.xml @@ -12,10 +12,6 @@ - - org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern - .*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$ - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml deleted file mode 100644 index 374a4a02129..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - boot.context.service.port - - - - - - - - - - - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml deleted file mode 100644 index 2bce7ed4b94..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - boot.webapp.service.port - - - - - - - - - - - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml index 217496d7d34..030a2e46832 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml @@ -33,7 +33,7 @@ - + boot.annotations.port diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml index c3d310790ad..82f0bb0841f 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml @@ -33,7 +33,7 @@ - + boot.bundle.port diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml index 5b5e7d54cb0..e21afb24057 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml @@ -33,7 +33,7 @@ - + boot.jakarta.websocket.port diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml index 87ab46d7181..1b1f7b8dbb1 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml @@ -33,7 +33,7 @@ - + boot.jsp.port diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml index 7df0151bfdd..a1b677bc6ec 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml @@ -32,7 +32,7 @@ - + boot.resources.port diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml index f5519072d60..d5230f18f43 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml @@ -33,7 +33,7 @@ - + boot.websocket.port diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http2.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http2.xml index 2bf9d1051b1..bd0226dd58d 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http2.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-http2.xml @@ -1,9 +1,6 @@ - - - @@ -12,6 +9,12 @@ + + + + + + @@ -21,13 +24,6 @@ true - - - - TLSv1.3 - - - diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-https.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-https.xml index b140e422084..a71de579531 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-https.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-https.xml @@ -16,13 +16,7 @@ - - - - boot.https.port - - - + diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl-context.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl-context.xml new file mode 100644 index 00000000000..8e4fbbc87bf --- /dev/null +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl-context.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl.xml index b25525dec5c..f58ee8c3573 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-ssl.xml @@ -4,7 +4,7 @@ - + @@ -15,30 +15,34 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - / - - / - - - - - @@ -48,7 +52,14 @@ - + + + + + + + + diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-testrealm.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-testrealm.xml index e9ebabc4699..2bcb43402e4 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-testrealm.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty-testrealm.xml @@ -8,12 +8,21 @@ - - - - Test Realm - /etc/realm.properties - - + + + + /etc/realm.properties + + + + + + Test Realm + + false + + + + diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty.xml b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty.xml index 58bcafde431..4e8ac736b60 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty.xml +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/config/etc/jetty.xml @@ -64,32 +64,6 @@ - - - - - - org.eclipse.jetty.ee10.webapp.FragmentConfiguration - org.eclipse.jetty.ee10.webapp.JettyWebXmlConfiguration - org.eclipse.jetty.ee10.webapp.WebXmlConfiguration - org.eclipse.jetty.ee10.webapp.WebAppConfiguration - org.eclipse.jetty.ee10.webapp.ServletsConfiguration - org.eclipse.jetty.ee10.webapp.JspConfiguration - org.eclipse.jetty.ee10.webapp.JaasConfiguration - org.eclipse.jetty.ee10.webapp.JndiConfiguration - org.eclipse.jetty.ee10.plus.webapp.PlusConfiguration - org.eclipse.jetty.ee10.plus.webapp.EnvConfiguration - org.eclipse.jetty.ee10.webapp.JmxConfiguration - org.eclipse.jetty.ee10.osgi.annotations.AnnotationConfiguration - org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration - org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketConfiguration - org.eclipse.jetty.ee10.osgi.boot.OSGiWebInfConfiguration - org.eclipse.jetty.ee10.osgi.boot.OSGiMetaInfConfiguration - - - - - java.naming.factory.initial diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiAnnotationParser.java b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiAnnotationParser.java index bb09e30dcce..97f807d2fef 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiAnnotationParser.java +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiAnnotationParser.java @@ -26,8 +26,8 @@ import javax.inject.Inject; import aQute.bnd.osgi.Constants; import org.eclipse.jetty.ee10.annotations.ClassInheritanceHandler; import org.eclipse.jetty.ee10.osgi.annotations.AnnotationParser; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.junit.Test; -import org.junit.jupiter.api.Disabled; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.CoreOptions; @@ -46,8 +46,7 @@ import static org.ops4j.pax.exam.CoreOptions.mavenBundle; * TestJettyOSGiAnnotationParser * */ -@Disabled //TODO -//@RunWith(PaxExam.class) +@RunWith(PaxExam.class) public class TestJettyOSGiAnnotationParser { @Inject @@ -88,10 +87,9 @@ public class TestJettyOSGiAnnotationParser //test the osgi annotation parser ignore the module-info.class file in the fake bundle //Get a reference to the deployed fake bundle Bundle b = TestOSGiUtil.getBundle(bundleContext, "bundle.with.module.info"); - AnnotationParser parser = new AnnotationParser(0); - parser.indexBundle(b); + AnnotationParser parser = new AnnotationParser(); + parser.indexBundle(ResourceFactory.root(), b); ClassInheritanceHandler handler = new ClassInheritanceHandler(new ConcurrentHashMap<>()); parser.parse(Collections.singleton(handler), b); - } } diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootContextAsService.java b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootContextAsService.java deleted file mode 100644 index a0496708cfe..00000000000 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootContextAsService.java +++ /dev/null @@ -1,116 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.osgi.test; - -import java.util.ArrayList; -import javax.inject.Inject; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.junit.Test; -import org.junit.jupiter.api.Disabled; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.CoreOptions; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.junit.PaxExam; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.ops4j.pax.exam.CoreOptions.mavenBundle; -import static org.ops4j.pax.exam.CoreOptions.systemProperty; - -/** - * TestJettyOSGiBootContextAsService - * - * Tests deployment of a ContextHandler as an osgi Service. - * - * Tests the ServiceContextProvider. - */ -@Disabled //TODO -//@RunWith(PaxExam.class) -public class TestJettyOSGiBootContextAsService -{ - @Inject - BundleContext bundleContext = null; - - @Configuration - public static Option[] configure() - { - ArrayList diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/jettyhome/etc/jetty.xml b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/jettyhome/etc/jetty.xml index b2ef246de8c..00bd315b460 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/jettyhome/etc/jetty.xml +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/jettyhome/etc/jetty.xml @@ -1,7 +1,6 @@ - @@ -37,18 +36,7 @@ - + @@ -74,34 +62,6 @@ - - - - - - - org.eclipse.jetty.ee9.webapp.FragmentConfiguration - org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration - org.eclipse.jetty.ee9.webapp.WebXmlConfiguration - org.eclipse.jetty.ee9.webapp.WebAppConfiguration - org.eclipse.jetty.ee9.webapp.ServletsConfiguration - org.eclipse.jetty.ee9.webapp.JspConfiguration - org.eclipse.jetty.ee9.webapp.JaasConfiguration - org.eclipse.jetty.ee9.webapp.JndiConfiguration - org.eclipse.jetty.plus.webapp.PlusConfiguration - org.eclipse.jetty.plus.webapp.EnvConfiguration - org.eclipse.jetty.ee9.webapp.JmxConfiguration - org.eclipse.jetty.ee9.osgi.annotations.AnnotationConfiguration - org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration - org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketConfiguration - org.eclipse.jetty.ee9.osgi.boot.OSGiWebInfConfiguration - org.eclipse.jetty.ee9.osgi.boot.OSGiMetaInfConfiguration - - - - - - java.naming.factory.initial diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/pom.xml b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/pom.xml index 1504d0dd4e5..13c1b279419 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/pom.xml +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/pom.xml @@ -25,7 +25,7 @@ org.eclipse.jetty - jetty-deploy + jetty-osgi ${project.version} @@ -56,6 +56,11 @@ + + + src/main/resources + + maven-antrun-plugin @@ -85,8 +90,8 @@ org.eclipse.jetty.ee9.osgi.boot;singleton:=true - org.eclipse.jetty.ee9.osgi.boot.JettyBootstrapActivator - org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))" + org.eclipse.jetty.ee9.osgi.boot.EE9Activator + org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))", org.eclipse.jetty.ee9.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))" ${osgi.slf4j.import.packages}, jakarta.mail;version="2.0";resolution:=optional, @@ -109,7 +114,7 @@ org.osgi.util.tracker;version="${osgi-util-tracker-version}", org.xml.sax, org.xml.sax.helpers, - org.eclipse.jetty.annotations;resolution:=optional, + org.eclipse.jetty.ee9.annotations;resolution:=optional, * diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationConfiguration.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationConfiguration.java index a6d553ea539..95c6c999901 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationConfiguration.java +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationConfiguration.java @@ -21,11 +21,13 @@ import java.util.Set; import jakarta.servlet.ServletContainerInitializer; import org.eclipse.jetty.ee9.annotations.AnnotationParser.Handler; import org.eclipse.jetty.ee9.osgi.boot.OSGiMetaInfConfiguration; -import org.eclipse.jetty.ee9.osgi.boot.OSGiWebappConstants; import org.eclipse.jetty.ee9.webapp.Configuration; import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.osgi.OSGiWebappConstants; +import org.eclipse.jetty.util.FileID; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; @@ -80,13 +82,13 @@ public class AnnotationConfiguration extends org.eclipse.jetty.ee9.annotations.A * This parser scans the bundles using the OSGi APIs instead of assuming a jar. */ @Override - protected org.eclipse.jetty.ee9.annotations.AnnotationParser createAnnotationParser(int javaTargetVersion) + protected org.eclipse.jetty.ee9.annotations.AnnotationParser createAnnotationParser() { - return new AnnotationParser(javaTargetVersion); + return new AnnotationParser(); } @Override - public Resource getJarFor(ServletContainerInitializer service) throws MalformedURLException, IOException + public Resource getJarFor(ServletContainerInitializer service) { Resource resource = super.getJarFor(service); // TODO This is not correct, but implemented like this to be bug for bug compatible @@ -127,7 +129,7 @@ public class AnnotationConfiguration extends org.eclipse.jetty.ee9.annotations.A if (bundle.getState() == Bundle.UNINSTALLED) continue; - Resource bundleRes = oparser.indexBundle(bundle); + Resource bundleRes = oparser.indexBundle(ResourceFactory.of(context), bundle); if (!context.getMetaData().getWebInfResources(false).contains(bundleRes)) { context.getMetaData().addWebInfResource(bundleRes); @@ -142,7 +144,7 @@ public class AnnotationConfiguration extends org.eclipse.jetty.ee9.annotations.A } } //scan ourselves - oparser.indexBundle(webbundle); + oparser.indexBundle(ResourceFactory.of(context), webbundle); parseWebBundle(context, oparser, webbundle); _webInfLibStats.increment(); diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationParser.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationParser.java index a20ec8abbd1..2265b4ed59a 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationParser.java +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationParser.java @@ -24,40 +24,47 @@ import java.util.StringTokenizer; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.util.FileID; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * */ public class AnnotationParser extends org.eclipse.jetty.ee9.annotations.AnnotationParser { - private Set _alreadyParsed = ConcurrentHashMap.newKeySet(); + private static final Logger LOG = LoggerFactory.getLogger(AnnotationParser.class); + + private Set _parsed = ConcurrentHashMap.newKeySet(); private ConcurrentHashMap _uriToBundle = new ConcurrentHashMap<>(); private ConcurrentHashMap _bundleToResource = new ConcurrentHashMap<>(); private ConcurrentHashMap _resourceToBundle = new ConcurrentHashMap<>(); private ConcurrentHashMap _bundleToUri = new ConcurrentHashMap<>(); - public AnnotationParser(int javaPlatform) + public AnnotationParser() { - super(javaPlatform); + super(); } /** * Keep track of a jetty URI Resource and its associated OSGi bundle. * + *@param resourceFactory the ResourceFactory to convert bundle location * @param bundle the bundle to index * @return the resource for the bundle * @throws Exception if unable to create the resource reference */ - public Resource indexBundle(Bundle bundle) throws Exception + public Resource indexBundle(ResourceFactory resourceFactory, Bundle bundle) throws Exception { File bundleFile = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); - Resource resource = Resource.newResource(bundleFile.toURI()); + Resource resource = resourceFactory.newResource(bundleFile.toURI()); URI uri = resource.getURI(); _uriToBundle.putIfAbsent(uri, bundle); _bundleToUri.putIfAbsent(bundle, uri); @@ -81,145 +88,54 @@ public class AnnotationParser extends org.eclipse.jetty.ee9.annotations.Annotati return _resourceToBundle.get(resource); } - /** - * - */ - @Override - public void parse(Set handlers, URI[] uris) - throws Exception - { - for (URI uri : uris) - { - Bundle associatedBundle = _uriToBundle.get(uri); - if (associatedBundle == null) - { - if (!_alreadyParsed.add(uri)) - { - continue; - } - //a jar in WEB-INF/lib or the WEB-INF/classes - //use the behavior of the super class for a standard jar. - super.parse(handlers, new URI[]{uri}); - } - else - { - parse(handlers, associatedBundle); - } - } - } - public void parse(Set handlers, Bundle bundle) throws Exception { - URI uri = _bundleToUri.get(bundle); - if (!_alreadyParsed.add(uri)) + + Resource bundleResource = _bundleToResource.get(bundle); + if (bundleResource == null) + return; + + if (!_parsed.add(_bundleToUri.get(bundle))) + return; + + + parse(handlers, bundleResource); + } + + @Override + public void parse(final Set handlers, Resource r) throws Exception + { + if (r == null) + return; + + if (FileID.isJavaArchive(r.getPath())) { + parseJar(handlers, r); return; } - String bundleClasspath = (String)bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH); - if (bundleClasspath == null) - { - bundleClasspath = "."; - } - //order the paths first by the number of tokens in the path second alphabetically. - TreeSet paths = new TreeSet<>( - new Comparator() - { - @Override - public int compare(String o1, String o2) - { - int paths1 = new StringTokenizer(o1, "/", false).countTokens(); - int paths2 = new StringTokenizer(o2, "/", false).countTokens(); - if (paths1 == paths2) - { - return o1.compareTo(o2); - } - return paths2 - paths1; - } - }); - boolean hasDotPath = false; - StringTokenizer tokenizer = new StringTokenizer(bundleClasspath, StringUtil.DEFAULT_DELIMS, false); - while (tokenizer.hasMoreTokens()) - { - String token = tokenizer.nextToken().trim(); - if (!token.startsWith("/")) - { - token = "/" + token; - } - if (token.equals("/.")) - { - hasDotPath = true; - } - else if (!FileID.isJavaArchive(token) && !token.endsWith("/")) - { - paths.add(token + "/"); - } - else - { - paths.add(token); - } - } - //support the development environment: maybe the classes are inside bin or target/classes - //this is certainly not useful in production. - //however it makes our life so much easier during development. - if (bundle.getEntry("/.classpath") != null) - { - if (bundle.getEntry("/bin/") != null) - { - paths.add("/bin/"); - } - else if (bundle.getEntry("/target/classes/") != null) - { - paths.add("/target/classes/"); - } - } - @SuppressWarnings("rawtypes") - Enumeration classes = bundle.findEntries("/", "*.class", true); - if (classes == null) + if (r.isDirectory()) { + parseDir(handlers, r); return; } - while (classes.hasMoreElements()) + + if (FileID.isClassFile(r.getPath())) { - URL classUrl = (URL)classes.nextElement(); - String path = classUrl.getPath(); - //remove the longest path possible: - String name = null; - for (String prefixPath : paths) - { - if (path.startsWith(prefixPath)) - { - name = path.substring(prefixPath.length()); - break; - } - } - if (name == null && hasDotPath) - { - //remove the starting '/' - name = path.substring(1); - } - if (name == null) - { - //found some .class file in the archive that was not under one of the prefix paths - //or the bundle classpath wasn't simply ".", so skip it - continue; - } - - if (!isValidClassFileName(name)) - { - continue; //eg skip module-info.class - } - - //transform into a classname to pass to the resolver - String shortName = StringUtil.replace(name, '/', '.').substring(0, name.length() - 6); - - addParsedClass(shortName, getResource(bundle)); - - try (InputStream classInputStream = classUrl.openStream()) - { - scanClass(handlers, getResource(bundle), classInputStream); - } + parseClass(handlers, null, r.getPath()); + } + + //Not already parsed, it could be a file that actually is compressed but does not have + //.jar/.zip etc extension, such as equinox urls, so try to parse it + try + { + parseJar(handlers, r); + } + catch (Exception e) + { + if (LOG.isDebugEnabled()) + LOG.warn("Resource not able to be scanned for classes: {}", r); } } } diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractContextProvider.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractContextProvider.java deleted file mode 100644 index f0b44f1d19f..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractContextProvider.java +++ /dev/null @@ -1,230 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import java.io.File; -import java.util.Dictionary; -import java.util.HashMap; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee9.osgi.boot.utils.OSGiClassLoader; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.resource.JarResource; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.osgi.framework.Bundle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractContextProvider - * - * Base class for DeploymentManager Providers that can deploy ContextHandlers into - * Jetty that have been discovered via OSGI either as bundles or services. - */ -public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); - - private DeploymentManager _deploymentManager; - - private ServerInstanceWrapper _serverWrapper; - - /** - * OSGiApp - */ - public class OSGiApp extends AbstractOSGiApp - { - private String _contextFile; - private ContextHandler _contextHandler; - private boolean _configured = false; - - public OSGiApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile) - { - super(manager, provider, bundle, originId); - _contextFile = contextFile; - } - - public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String contextFile, String originId) - { - super(manager, provider, bundle, properties, originId); - _contextFile = contextFile; - } - - public String getContextFile() - { - return _contextFile; - } - - public void setHandler(ContextHandler h) - { - _contextHandler = h; - } - - public ContextHandler createContextHandler() - throws Exception - { - configureContextHandler(); - return _contextHandler; - } - - public void configureContextHandler() - throws Exception - { - if (_configured) - return; - - _configured = true; - - //Override for bundle root may have been set - String bundleOverrideLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); - - //Location on filesystem of bundle or the bundle override location - File bundleLocation = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle); - File root = (bundleOverrideLocation == null ? bundleLocation : new File(bundleOverrideLocation)); - Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(root.toURI().toURL())); - - //try and make sure the rootResource is useable - if its a jar then make it a jar file url - if (rootResource.exists() && !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:")) - { - Resource jarResource = JarResource.newJarResource(rootResource); - if (jarResource.exists() && jarResource.isDirectory()) - rootResource = jarResource; - } - - //Set the base resource of the ContextHandler, if not already set, can also be overridden by the context xml file - if (_contextHandler != null && _contextHandler.getBaseResource() == null) - { - _contextHandler.setBaseResource(rootResource); - } - - //Use a classloader that knows about the common jetty parent loader, and also the bundle - OSGiClassLoader classLoader = new OSGiClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps(), _bundle); - - //if there is a context file, find it and apply it - if (_contextFile == null && _contextHandler == null) - throw new IllegalStateException("No context file or ContextHandler"); - - if (_contextFile != null) - { - //apply the contextFile, creating the ContextHandler, the DeploymentManager will register it in the ContextHandlerCollection - Resource res = null; - - String jettyHome = (String)getServerInstanceWrapper().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); - if (jettyHome == null) - jettyHome = System.getProperty(OSGiServerConstants.JETTY_HOME); - - res = findFile(_contextFile, jettyHome, bundleOverrideLocation, _bundle); - - //apply the context xml file, either to an existing ContextHandler, or letting the - //it create the ContextHandler as necessary - if (res != null) - { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - - if (LOG.isDebugEnabled()) - LOG.debug("Context classloader = {}", cl); - try - { - Thread.currentThread().setContextClassLoader(classLoader); - - XmlConfiguration xmlConfiguration = new XmlConfiguration(res); - HashMap properties = new HashMap(); - //put the server instance in - properties.put("Server", getServerInstanceWrapper().getServer()); - //put in the location of the bundle root - properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString()); - - // insert the bundle's location as a property. - xmlConfiguration.getProperties().putAll(properties); - - if (_contextHandler == null) - _contextHandler = (ContextHandler)xmlConfiguration.configure(); - else - xmlConfiguration.configure(_contextHandler); - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - } - - //Set up the class loader we created - _contextHandler.setClassLoader(classLoader); - - //If a bundle/service property specifies context path, let it override the context xml - String contextPath = (String)_properties.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - if (contextPath != null) - _contextHandler.setContextPath(contextPath); - - //osgi Enterprise Spec r4 p.427 - _contextHandler.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, _bundle.getBundleContext()); - - //make sure we protect also the osgi dirs specified by OSGi Enterprise spec - String[] targets = _contextHandler.getProtectedTargets(); - int length = (targets == null ? 0 : targets.length); - - String[] updatedTargets = null; - if (targets != null) - { - updatedTargets = new String[length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(targets, 0, updatedTargets, 0, length); - } - else - updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); - _contextHandler.setProtectedTargets(updatedTargets); - } - } - - public AbstractContextProvider(ServerInstanceWrapper wrapper) - { - _serverWrapper = wrapper; - } - - public ServerInstanceWrapper getServerInstanceWrapper() - { - return _serverWrapper; - } - - @Override - public ContextHandler createContextHandler(App app) throws Exception - { - if (app == null) - return null; - if (!(app instanceof OSGiApp)) - throw new IllegalStateException(app + " is not a BundleApp"); - - //Create a ContextHandler suitable to deploy in OSGi - ContextHandler h = ((OSGiApp)app).createContextHandler(); - return h; - } - - @Override - public void setDeploymentManager(DeploymentManager deploymentManager) - { - _deploymentManager = deploymentManager; - } - - public DeploymentManager getDeploymentManager() - { - return _deploymentManager; - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractOSGiApp.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractOSGiApp.java deleted file mode 100644 index 7feb13107ec..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractOSGiApp.java +++ /dev/null @@ -1,195 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import java.io.File; -import java.net.URL; -import java.util.Dictionary; -import java.util.Hashtable; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.resource.Resource; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceRegistration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractOSGiApp - * - * Base class representing info about a webapp/ContextHandler that is deployed into Jetty. - */ -public abstract class AbstractOSGiApp extends App -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractOSGiApp.class); - - protected Bundle _bundle; - protected Dictionary _properties; - protected ServiceRegistration _registration; - - public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId) - { - this(manager, provider, bundle, bundle.getHeaders(), originId); - } - - public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId) - { - super(manager, provider, originId); - _properties = properties; - _bundle = bundle; - } - - public String getBundleSymbolicName() - { - return _bundle.getSymbolicName(); - } - - public String getBundleVersionAsString() - { - if (_bundle.getVersion() == null) - return null; - return _bundle.getVersion().toString(); - } - - public Bundle getBundle() - { - return _bundle; - } - - public void setRegistration(ServiceRegistration registration) - { - _registration = registration; - } - - public ServiceRegistration getRegistration() - { - return _registration; - } - - public void registerAsOSGiService() throws Exception - { - if (_registration == null) - { - Dictionary properties = new Hashtable(); - properties.put(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK); - if (getBundleSymbolicName() != null) - properties.put(OSGiWebappConstants.OSGI_WEB_SYMBOLICNAME, getBundleSymbolicName()); - if (getBundleVersionAsString() != null) - properties.put(OSGiWebappConstants.OSGI_WEB_VERSION, getBundleVersionAsString()); - properties.put(OSGiWebappConstants.OSGI_WEB_CONTEXTPATH, getContextPath()); - ServiceRegistration rego = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ContextHandler.class.getName(), getContextHandler(), properties); - setRegistration(rego); - } - } - - protected void deregisterAsOSGiService() throws Exception - { - if (_registration == null) - return; - - _registration.unregister(); - _registration = null; - } - - protected Resource getFileAsResource(String dir, String file) - { - Resource r = null; - try - { - File asFile = new File(dir, file); - if (asFile.exists()) - r = Resource.newResource(asFile); - } - catch (Exception e) - { - r = null; - } - return r; - } - - protected Resource getFileAsResource(String file) - { - Resource r = null; - try - { - File asFile = new File(file); - if (asFile.exists()) - r = Resource.newResource(asFile); - } - catch (Exception e) - { - r = null; - } - return r; - } - - protected Resource findFile(String fileName, String jettyHome, String bundleOverrideLocation, Bundle containingBundle) - { - Resource res = null; - - //try to find the context file in the filesystem - if (fileName.startsWith("/")) - res = getFileAsResource(fileName); - if (res != null) - return res; - - //try to find it relative to jetty home - if (jettyHome != null) - { - if (jettyHome.startsWith("\"") || jettyHome.startsWith("'")) - jettyHome = jettyHome.substring(1); - if (jettyHome.endsWith("\"") || (jettyHome.endsWith("'"))) - jettyHome = jettyHome.substring(0, jettyHome.length() - 1); - - res = getFileAsResource(jettyHome, fileName); - } - if (res != null) - return res; - - //try to find it relative to an override location that has been specified - if (bundleOverrideLocation != null) - { - try (Resource location = Resource.newResource(bundleOverrideLocation)) - { - res = location.addPath(fileName); - } - catch (Exception e) - { - LOG.warn("Unable to find relative override location: {}", bundleOverrideLocation, e); - } - } - if (res != null) - return res; - - //try to find it relative to the bundle in which it is being deployed - if (containingBundle != null) - { - if (fileName.startsWith("./")) - fileName = fileName.substring(1); - - if (!fileName.startsWith("/")) - fileName = "/" + fileName; - - URL entry = _bundle.getEntry(fileName); - if (entry != null) - res = Resource.newResource(entry); - } - - return res; - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractWebAppProvider.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractWebAppProvider.java deleted file mode 100644 index f06da7f93eb..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/AbstractWebAppProvider.java +++ /dev/null @@ -1,553 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import java.io.File; -import java.net.URI; -import java.net.URL; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.HashMap; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee9.osgi.boot.internal.webapp.OSGiWebappClassLoader; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee9.webapp.WebAppClassLoader; -import org.eclipse.jetty.ee9.webapp.WebAppContext; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.resource.JarResource; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.service.packageadmin.PackageAdmin; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractWebAppProvider - *

- * Base class for Jetty DeploymentManager Providers that are capable of deploying a webapp, - * either from a bundle or an OSGi service. - */ -public abstract class AbstractWebAppProvider extends AbstractLifeCycle implements AppProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); - - private boolean _parentLoaderPriority; - - private String _defaultsDescriptor; - - private boolean _extractWars = true; //See WebAppContext.extractWars - - private String _tldBundles; - - private DeploymentManager _deploymentManager; - - private ServerInstanceWrapper _serverWrapper; - - /** - * OSGiApp - * - * Represents a deployable webapp. - */ - public class OSGiApp extends AbstractOSGiApp - { - private String _contextPath; - private String _webAppPath; - private WebAppContext _webApp; - - public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId) - { - super(manager, provider, bundle, originId); - } - - public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId) - { - super(manager, provider, bundle, properties, originId); - } - - public void setWebAppContext(WebAppContext webApp) - { - _webApp = webApp; - } - - @Override - public String getContextPath() - { - return _contextPath; - } - - public void setContextPath(String contextPath) - { - this._contextPath = contextPath; - } - - public String getBundlePath() - { - return _webAppPath; - } - - public void setWebAppPath(String path) - { - this._webAppPath = path; - } - - public ContextHandler createContextHandler() - throws Exception - { - if (_webApp != null) - { - configureWebApp(); - return _webApp; - } - - createWebApp(); - return _webApp; - } - - protected void createWebApp() - throws Exception - { - _webApp = newWebApp(); - configureWebApp(); - } - - protected WebAppContext newWebApp() - { - WebAppContext webApp = new WebAppContext(); - webApp.setAttribute(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK); - - //make sure we protect also the osgi dirs specified by OSGi Enterprise spec - String[] targets = webApp.getProtectedTargets(); - String[] updatedTargets = null; - if (targets != null) - { - updatedTargets = new String[targets.length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(targets, 0, updatedTargets, 0, targets.length); - } - else - updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; - System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, targets.length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); - webApp.setProtectedTargets(updatedTargets); - - return webApp; - } - - public void configureWebApp() - throws Exception - { - //TODO turn this around and let any context.xml file get applied first, and have the properties override - _webApp.setContextPath(_contextPath); - - //osgi Enterprise Spec r4 p.427 - _webApp.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, _bundle.getBundleContext()); - - String overrideBundleInstallLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); - File bundleInstallLocation = - (overrideBundleInstallLocation == null - ? BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle) - : new File(overrideBundleInstallLocation)); - - if (LOG.isDebugEnabled()) - { - LOG.debug("Bundle location is {}, install location: {}", _bundle.getLocation(), bundleInstallLocation); - } - - URL url = null; - Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(bundleInstallLocation.toURI().toURL())); - //try and make sure the rootResource is useable - if its a jar then make it a jar file url - if (rootResource.exists() && !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:")) - { - Resource jarResource = JarResource.newJarResource(rootResource); - if (jarResource.exists() && jarResource.isDirectory()) - rootResource = jarResource; - } - - //if the path wasn't set or it was ., then it is the root of the bundle's installed location - if (_webAppPath == null || _webAppPath.length() == 0 || ".".equals(_webAppPath)) - { - url = bundleInstallLocation.toURI().toURL(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using bundle install location: {}", url); - } - else - { - //Get the location of the root of the webapp inside the installed bundle - if (_webAppPath.startsWith("/") || _webAppPath.startsWith("file:")) - { - url = new File(_webAppPath).toURI().toURL(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using absolute location: {}", url); - } - else if (bundleInstallLocation != null && bundleInstallLocation.isDirectory()) - { - url = new File(bundleInstallLocation, _webAppPath).toURI().toURL(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using path relative to bundle unpacked install location: {}", url); - } - else if (bundleInstallLocation != null) - { - Enumeration urls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(_bundle, _webAppPath); - if (urls != null && urls.hasMoreElements()) - { - url = urls.nextElement(); - if (LOG.isDebugEnabled()) - LOG.debug("Webapp base using path relative to packed bundle location: {}", url); - } - } - } - - if (url == null) - { - throw new IllegalArgumentException("Unable to locate " + _webAppPath + " in " + - (bundleInstallLocation != null ? bundleInstallLocation.getAbsolutePath() : "unlocated bundle '" + _bundle.getSymbolicName() + "'")); - } - - //Sets the location of the war file - // converts bundleentry: protocol if necessary - _webApp.setWar(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(url).toString()); - - // Set up what has been configured on the provider - _webApp.setParentLoaderPriority(isParentLoaderPriority()); - _webApp.setExtractWAR(isExtract()); - - //Set up configuration from manifest headers - //extra classpath - String tmp = (String)_properties.get(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH); - if (tmp != null) - _webApp.setExtraClasspath(tmp); - - //web.xml - tmp = (String)_properties.get(OSGiWebappConstants.JETTY_WEB_XML_PATH); - if (tmp != null && tmp.trim().length() != 0) - { - File webXml = getFile(tmp, bundleInstallLocation); - if (webXml != null && webXml.exists()) - _webApp.setDescriptor(webXml.getAbsolutePath()); - } - - // webdefault-ee9.xml - tmp = (String)_properties.get(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH); - if (tmp != null) - { - File defaultWebXml = getFile(tmp, bundleInstallLocation); - if (defaultWebXml != null) - { - if (defaultWebXml.exists()) - _webApp.setDefaultsDescriptor(defaultWebXml.getAbsolutePath()); - else - LOG.warn("{} does not exist", defaultWebXml.getAbsolutePath()); - } - } - - //Handle Require-TldBundle - //This is a comma separated list of names of bundles that contain tlds that this webapp uses. - //We add them to the webapp classloader. - String requireTldBundles = (String)_properties.get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); - String pathsToTldBundles = getPathsToRequiredBundles(requireTldBundles); - - // make sure we provide access to all the jetty bundles by going - // through this bundle. - OSGiWebappClassLoader webAppLoader = new OSGiWebappClassLoader(_serverWrapper.getParentClassLoaderForWebapps(), _webApp, _bundle); - - if (pathsToTldBundles != null) - webAppLoader.addClassPath(pathsToTldBundles); - _webApp.setClassLoader(webAppLoader); - - // apply any META-INF/context.xml file that is found to configure - // the webapp first - try - { - final Resource finalRootResource = rootResource; - WebAppClassLoader.runWithServerClassAccess(() -> - { - applyMetaInfContextXml(finalRootResource, overrideBundleInstallLocation); - return null; - }); - } - catch (Exception e) - { - LOG.warn("Error applying context xml"); - throw e; - } - - _webApp.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundles); - - //Set up some attributes - // rfc66 - _webApp.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT, _bundle.getBundleContext()); - - // spring-dm-1.2.1 looks for the BundleContext as a different attribute. - // not a spec... but if we want to support - // org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext - // then we need to do this to: - _webApp.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), _bundle.getBundleContext()); - - // also pass the bundle directly. sometimes a bundle does not have a - // bundlecontext. - // it is still useful to have access to the Bundle from the servlet - // context. - _webApp.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, _bundle); - } - - protected String getPathsToRequiredBundles(String requireTldBundles) - throws Exception - { - if (requireTldBundles == null) - return null; - - ServiceReference ref = _bundle.getBundleContext().getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName()); - PackageAdmin packageAdmin = (ref == null) ? null : (PackageAdmin)_bundle.getBundleContext().getService(ref); - if (packageAdmin == null) - throw new IllegalStateException("Unable to get PackageAdmin reference to locate required Tld bundles"); - - StringBuilder paths = new StringBuilder(); - String[] symbNames = requireTldBundles.split("[, ]"); - - for (String symbName : symbNames) - { - Bundle[] bs = packageAdmin.getBundles(symbName, null); - if (bs == null || bs.length == 0) - { - throw new IllegalArgumentException("Unable to locate the bundle '" + symbName + "' specified by " + - OSGiWebappConstants.REQUIRE_TLD_BUNDLE + " in manifest of " + - (_bundle == null ? "unknown" : _bundle.getSymbolicName())); - } - - File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bs[0]); - if (paths.length() > 0) - paths.append(", "); - paths.append(f.toURI().toURL().toString()); - if (LOG.isDebugEnabled()) - LOG.debug("getPathsToRequiredBundles: bundle path={} uri={}", bs[0].getLocation(), f.toURI()); - } - - return paths.toString(); - } - - protected void applyMetaInfContextXml(Resource rootResource, String overrideBundleInstallLocation) - throws Exception - { - if (_bundle == null) - return; - if (_webApp == null) - return; - - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (LOG.isDebugEnabled()) - LOG.debug("Context classloader = {}", cl); - try - { - - Thread.currentThread().setContextClassLoader(_webApp.getClassLoader()); - - URI contextXmlUri = null; - - //TODO replace this with getting the InputStream so we don't cache in URL - //Try looking for a context xml file in META-INF with a specific name - URL url = _bundle.getEntry("/META-INF/jetty-webapp-context.xml"); - if (url != null) - { - contextXmlUri = url.toURI(); - } - - if (contextXmlUri == null) - { - //Didn't find specially named file, try looking for a property that names a context xml file to use - if (_properties != null) - { - String tmp = (String)_properties.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); - if (tmp != null) - { - String[] filenames = tmp.split("[,;]"); - if (filenames != null && filenames.length > 0) - { - String filename = filenames[0]; //should only be 1 filename in this usage - String jettyHome = (String)getServerInstanceWrapper().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); - if (jettyHome == null) - jettyHome = System.getProperty(OSGiServerConstants.JETTY_HOME); - Resource res = findFile(filename, jettyHome, overrideBundleInstallLocation, _bundle); - if (res != null) - { - contextXmlUri = res.getURI(); - } - } - } - } - } - if (contextXmlUri == null) - return; - - // Apply it just as the standard jetty ContextProvider would do - LOG.info("Applying {} to {}", contextXmlUri, _webApp); - - XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.newResource(contextXmlUri)); - WebAppClassLoader.runWithServerClassAccess(() -> - { - HashMap properties = new HashMap<>(); - xmlConfiguration.getIdMap().put("Server", getDeploymentManager().getServer()); - properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString()); - properties.put(OSGiServerConstants.JETTY_HOME, (String)getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME)); - xmlConfiguration.getProperties().putAll(properties); - xmlConfiguration.configure(_webApp); - return null; - }); - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - - private File getFile(String file, File bundleInstall) - { - if (file == null) - return null; - - if (file.startsWith("/") || file.startsWith("file:/")) //absolute location - return new File(file); - else - { - //relative location - //try inside the bundle first - File f = new File(bundleInstall, file); - if (f.exists()) - return f; - String jettyHome = (String)getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); - if (jettyHome != null) - return new File(jettyHome, file); - } - - return null; - } - } - - public AbstractWebAppProvider(ServerInstanceWrapper wrapper) - { - _serverWrapper = wrapper; - } - - /** - * Get the parentLoaderPriority. - * - * @return the parentLoaderPriority - */ - public boolean isParentLoaderPriority() - { - return _parentLoaderPriority; - } - - /** - * Set the parentLoaderPriority. - * - * @param parentLoaderPriority the parentLoaderPriority to set - */ - public void setParentLoaderPriority(boolean parentLoaderPriority) - { - _parentLoaderPriority = parentLoaderPriority; - } - - /** - * Get the defaultsDescriptor. - * - * @return the defaultsDescriptor - */ - public String getDefaultsDescriptor() - { - return _defaultsDescriptor; - } - - /** - * Set the defaultsDescriptor. - * - * @param defaultsDescriptor the defaultsDescriptor to set - */ - public void setDefaultsDescriptor(String defaultsDescriptor) - { - _defaultsDescriptor = defaultsDescriptor; - } - - public boolean isExtract() - { - return _extractWars; - } - - public void setExtract(boolean extract) - { - _extractWars = extract; - } - - /** - * @param tldBundles Comma separated list of bundles that contain tld jars - * that should be setup on the jetty instances created here. - */ - public void setTldBundles(String tldBundles) - { - _tldBundles = tldBundles; - } - - /** - * @return The list of bundles that contain tld jars that should be setup on - * the jetty instances created here. - */ - public String getTldBundles() - { - return _tldBundles; - } - - public void setServerInstanceWrapper(ServerInstanceWrapper wrapper) - { - _serverWrapper = wrapper; - } - - public ServerInstanceWrapper getServerInstanceWrapper() - { - return _serverWrapper; - } - - public DeploymentManager getDeploymentManager() - { - return _deploymentManager; - } - - @Override - public void setDeploymentManager(DeploymentManager deploymentManager) - { - _deploymentManager = deploymentManager; - } - - @Override - public ContextHandler createContextHandler(App app) throws Exception - { - if (app == null) - return null; - if (!(app instanceof OSGiApp)) - throw new IllegalStateException(app + " is not a BundleApp"); - - //Create a WebAppContext suitable to deploy in OSGi - ContextHandler ch = ((OSGiApp)app).createContextHandler(); - return ch; - } - - public static String getOriginId(Bundle contributor, String path) - { - return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() + (path.startsWith("/") ? path : "/" + path); - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleContextProvider.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleContextProvider.java deleted file mode 100644 index e6e2ab565b2..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/BundleContextProvider.java +++ /dev/null @@ -1,199 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.util.StringUtil; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleEvent; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.BundleTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * BundleContextProvider - *

- * Handles deploying OSGi bundles that define a context xml file for configuring them. - */ -public class BundleContextProvider extends AbstractContextProvider implements BundleProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); - - private Map _appMap = new HashMap(); - - private Map> _bundleMap = new HashMap>(); - - private ServiceRegistration _serviceRegForBundles; - - private BundleTracker _tracker; - - public class ContextBundleTracker extends BundleTracker - { - protected String _managedServerName; - - public ContextBundleTracker(BundleContext bundleContext, String managedServerName) - { - super(bundleContext, Bundle.ACTIVE | Bundle.STOPPING, null); - _managedServerName = managedServerName; - } - - @Override - public Object addingBundle(Bundle bundle, BundleEvent event) - { - try - { - String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME)) || - (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName)))) - { - if (bundleAdded(bundle)) - return bundle; - } - } - catch (Exception e) - { - LOG.warn("Unable to add bundle {}", bundle, e); - } - return null; - } - - @Override - public void removedBundle(Bundle bundle, BundleEvent event, Object object) - { - try - { - bundleRemoved(bundle); - } - catch (Exception e) - { - LOG.warn("Unable to remove bundle {}", bundle, e); - } - } - } - - public BundleContextProvider(ServerInstanceWrapper wrapper) - { - super(wrapper); - } - - @Override - protected void doStart() throws Exception - { - //Track bundles that are ContextHandlers that should be deployed - _tracker = new ContextBundleTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName()); - _tracker.open(); - - //register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to - Dictionary properties = new Hashtable(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); - _serviceRegForBundles = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(BundleProvider.class.getName(), this, properties); - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - _tracker.close(); - - //unregister ourselves - if (_serviceRegForBundles != null) - { - try - { - _serviceRegForBundles.unregister(); - } - catch (Exception e) - { - LOG.warn("Unable to unregister {}", _serviceRegForBundles, e); - } - } - } - - @Override - public boolean bundleAdded(Bundle bundle) throws Exception - { - if (bundle == null) - return false; - - //If the bundle defines a Web-ContextPath then its probably a webapp and the BundleWebAppProvider should deploy it - if ((String)bundle.getHeaders().get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("BundleContextProvider ignoring bundle {} with {} set", bundle.getSymbolicName(), OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - return false; - } - - String contextFiles = (String)bundle.getHeaders().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); - - if (contextFiles == null) - return false; - - boolean added = false; - //bundle defines JETTY_CONTEXT_FILE_PATH header, - //a comma separated list of context xml files that each define a ContextHandler - //TODO: (could be WebAppContexts) - String[] tmp = contextFiles.split("[,;]"); - for (String contextFile : tmp) - { - String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-" + contextFile; - OSGiApp app = new OSGiApp(getDeploymentManager(), this, originId, bundle, contextFile); - _appMap.put(originId, app); - List apps = _bundleMap.get(bundle); - if (apps == null) - { - apps = new ArrayList(); - _bundleMap.put(bundle, apps); - } - apps.add(app); - getDeploymentManager().addApp(app); - added = true; - } - - return added; //true if even 1 context from this bundle was added - } - - /** - * Bundle has been removed. If it was a context we deployed, undeploy it. - * - * @param bundle the bundle - * @return true if this was a context we had deployed, false otherwise - */ - @Override - public boolean bundleRemoved(Bundle bundle) throws Exception - { - List apps = _bundleMap.remove(bundle); - boolean removed = false; - if (apps != null) - { - for (App app : apps) - { - _appMap.remove(app.getOriginId()); - getDeploymentManager().removeApp(app); - removed = true; - } - } - return removed; //true if even 1 context was removed associated with this bundle - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/EE9Activator.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/EE9Activator.java new file mode 100644 index 00000000000..060e5e9e475 --- /dev/null +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/EE9Activator.java @@ -0,0 +1,611 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee9.osgi.boot; + +import java.io.File; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.eclipse.jetty.deploy.App; +import org.eclipse.jetty.deploy.AppProvider; +import org.eclipse.jetty.deploy.DeploymentManager; +import org.eclipse.jetty.ee9.webapp.Configuration; +import org.eclipse.jetty.ee9.webapp.Configurations; +import org.eclipse.jetty.ee9.webapp.WebAppClassLoader; +import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.osgi.AbstractContextProvider; +import org.eclipse.jetty.osgi.BundleContextProvider; +import org.eclipse.jetty.osgi.BundleWebAppProvider; +import org.eclipse.jetty.osgi.ContextFactory; +import org.eclipse.jetty.osgi.OSGiApp; +import org.eclipse.jetty.osgi.OSGiServerConstants; +import org.eclipse.jetty.osgi.OSGiWebappConstants; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.FakeURLClassLoader; +import org.eclipse.jetty.osgi.util.OSGiClassLoader; +import org.eclipse.jetty.osgi.util.ServerClasspathContributor; +import org.eclipse.jetty.osgi.util.Util; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.FileID; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.eclipse.jetty.util.resource.URLResourceFactory; +import org.eclipse.jetty.xml.XmlConfiguration; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * EE9Activator + *

+ * Enable deployment of webapps/contexts to EE9 + */ +public class EE9Activator implements BundleActivator +{ + private static final Logger LOG = LoggerFactory.getLogger(EE9Activator.class); + + public static final String ENVIRONMENT = "ee9"; + + private static Collection __serverClasspathContributors = new ArrayList<>(); + + public static void registerServerClasspathContributor(ServerClasspathContributor contributor) + { + __serverClasspathContributors.add(contributor); + } + + public static void unregisterServerClasspathContributor(ServerClasspathContributor contributor) + { + __serverClasspathContributors.remove(contributor); + } + + public static Collection getServerClasspathContributors() + { + return __serverClasspathContributors; + } + + /** + * ServerTracker + * + * Tracks appearance of Server instances as OSGi services, and then configures them + * for deployment of EE9 contexts and webapps. + * + */ + public static class ServerTracker implements ServiceTrackerCustomizer + { + private Bundle _myBundle = null; + + public ServerTracker(Bundle bundle) + { + _myBundle = bundle; + } + + @Override + public Object addingService(ServiceReference sr) + { + Bundle contributor = sr.getBundle(); + Server server = (Server)contributor.getBundleContext().getService(sr); + + //find bundles that should be on the container classpath and convert to URLs + List contributedURLs = new ArrayList<>(); + List contributedBundles = new ArrayList<>(); + Collection serverClasspathContributors = getServerClasspathContributors(); + serverClasspathContributors.stream().forEach(c -> contributedBundles.addAll(c.getScannableBundles())); + contributedBundles.stream().forEach(b -> contributedURLs.addAll(convertBundleToURL(b))); + + if (!contributedURLs.isEmpty()) + { + //There should already be a default set up by the JettyServerFactory + ClassLoader serverClassLoader = (ClassLoader)server.getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + if (serverClassLoader != null) + { + server.setAttribute(OSGiServerConstants.SERVER_CLASSLOADER, + new FakeURLClassLoader(serverClassLoader, contributedURLs.toArray(new URL[contributedURLs.size()]))); + + if (LOG.isDebugEnabled()) + LOG.debug("Server classloader for contexts = {}", server.getAttribute(OSGiServerConstants.SERVER_CLASSLOADER)); + } + server.setAttribute(OSGiServerConstants.SERVER_CLASSPATH_BUNDLES, contributedBundles); + } + + Optional deployer = getDeploymentManager(server); + BundleWebAppProvider webAppProvider = null; + BundleContextProvider contextProvider = null; + + String containerScanBundlePattern = null; + if (contributedBundles != null) + { + StringBuffer strbuff = new StringBuffer(); + contributedBundles.stream().forEach(b -> strbuff.append(b.getSymbolicName()).append("|")); + containerScanBundlePattern = strbuff.toString().substring(0, strbuff.length() - 1); + } + + if (deployer.isPresent()) + { + for (AppProvider provider : deployer.get().getAppProviders()) + { + if (BundleContextProvider.class.isInstance(provider) && ENVIRONMENT.equalsIgnoreCase(provider.getEnvironmentName())) + contextProvider = BundleContextProvider.class.cast(provider); + if (BundleWebAppProvider.class.isInstance(provider) && ENVIRONMENT.equalsIgnoreCase(provider.getEnvironmentName())) + webAppProvider = BundleWebAppProvider.class.cast(provider); + } + if (contextProvider == null) + { + contextProvider = new BundleContextProvider(ENVIRONMENT, server, new EE9ContextFactory(_myBundle)); + deployer.get().addAppProvider(contextProvider); + } + + if (webAppProvider == null) + { + webAppProvider = new BundleWebAppProvider(ENVIRONMENT, server, new EE9WebAppFactory(_myBundle)); + deployer.get().addAppProvider(webAppProvider); + } + + //ensure the providers are configured with the extra bundles that must be scanned from the container classpath + if (containerScanBundlePattern != null) + { + contextProvider.getProperties().put(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, containerScanBundlePattern); + webAppProvider.getProperties().put(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, containerScanBundlePattern); + } + } + else + LOG.info("No DeploymentManager for Server {}", server); + try + { + if (!server.isStarted()) + server.start(); + } + catch (Exception e) + { + LOG.warn("Failed to start server {}", server); + } + return server; + } + + @Override + public void modifiedService(ServiceReference reference, Object service) + { + removedService(reference, service); + addingService(reference); + } + + @Override + public void removedService(ServiceReference reference, Object service) + { + } + + private Optional getDeploymentManager(Server server) + { + Collection deployers = server.getBeans(DeploymentManager.class); + return deployers.stream().findFirst(); + } + + private List convertBundleToURL(Bundle bundle) + { + List urls = new ArrayList<>(); + try + { + File file = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); + + if (file.isDirectory()) + { + for (File f : file.listFiles()) + { + if (FileID.isJavaArchive(f.getName()) && f.isFile()) + { + urls.add(f.toURI().toURL()); + } + else if (f.isDirectory() && f.getName().equals("lib")) + { + for (File f2 : file.listFiles()) + { + if (FileID.isJavaArchive(f2.getName()) && f2.isFile()) + { + urls.add(f2.toURI().toURL()); + } + } + } + } + urls.add(file.toURI().toURL()); + } + else + { + urls.add(file.toURI().toURL()); + } + } + catch (Exception e) + { + LOG.warn("Unable to convert bundle {} to url", bundle, e); + } + + return urls; + } + } + + public static class EE9ContextFactory implements ContextFactory + { + private Bundle _myBundle; + + public EE9ContextFactory(Bundle bundle) + { + _myBundle = bundle; + } + + @Override + public ContextHandler createContextHandler(AbstractContextProvider provider, App app) + throws Exception + { + OSGiApp osgiApp = OSGiApp.class.cast(app); + String jettyHome = (String)app.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); + Path jettyHomePath = (StringUtil.isBlank(jettyHome) ? null : Paths.get(jettyHome)); + + ContextHandler contextHandler = new ContextHandler(); + + //Make base resource that of the bundle + contextHandler.setBaseResource(osgiApp.getBundleResource()); + + // provides access to core classes + ClassLoader coreLoader = (ClassLoader)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + if (LOG.isDebugEnabled()) + LOG.debug("Core classloader = {}", coreLoader.getClass()); + + //provide access to all ee9 classes + ClassLoader environmentLoader = new OSGiClassLoader(coreLoader, _myBundle); + + //Use a classloader that knows about the common jetty parent loader, and also the bundle + OSGiClassLoader classLoader = new OSGiClassLoader(environmentLoader, osgiApp.getBundle()); + contextHandler.setClassLoader(classLoader); + + //Apply any context xml file + String tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); + final URI contextXmlURI = Util.resolvePathAsLocalizedURI(tmp, osgiApp.getBundle(), jettyHomePath); + + if (contextXmlURI != null) + { + ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(contextHandler.getClassLoader()); + WebAppClassLoader.runWithServerClassAccess(() -> + { + XmlConfiguration xmlConfiguration = new XmlConfiguration(ResourceFactory.of(contextHandler).newResource(contextXmlURI)); + WebAppClassLoader.runWithServerClassAccess(() -> + { + Map properties = new HashMap<>(); + xmlConfiguration.getIdMap().put("Server", osgiApp.getDeploymentManager().getServer()); + properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, osgiApp.getPath().toUri().toString()); + properties.put(OSGiServerConstants.JETTY_HOME, (String)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME)); + xmlConfiguration.getProperties().putAll(properties); + xmlConfiguration.configure(contextHandler); + return null; + }); + return null; + }); + } + catch (Exception e) + { + LOG.warn("Error applying context xml", e); + throw e; + } + finally + { + Thread.currentThread().setContextClassLoader(oldLoader); + } + } + + //osgi Enterprise Spec r4 p.427 + contextHandler.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, osgiApp.getBundle().getBundleContext()); + + //make sure we protect also the osgi dirs specified by OSGi Enterprise spec + String[] targets = contextHandler.getProtectedTargets(); + int length = (targets == null ? 0 : targets.length); + + String[] updatedTargets = null; + if (targets != null) + { + updatedTargets = new String[length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(targets, 0, updatedTargets, 0, length); + } + else + updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); + contextHandler.setProtectedTargets(updatedTargets); + + return contextHandler; + } + } + + public static class EE9WebAppFactory implements ContextFactory + { + private Bundle _myBundle; + + public EE9WebAppFactory(Bundle bundle) + { + _myBundle = bundle; + } + + @Override + public ContextHandler createContextHandler(AbstractContextProvider provider, App app) + throws Exception + { + OSGiApp osgiApp = OSGiApp.class.cast(app); + String jettyHome = (String)app.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME); + Path jettyHomePath = (StringUtil.isBlank(jettyHome) ? null : Paths.get(jettyHome)); + + WebAppContext webApp = new WebAppContext(); + + //Apply defaults from the deployer providers + webApp.initializeDefaults(provider.getProperties()); + + // provides access to core classes + ClassLoader coreLoader = (ClassLoader)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.SERVER_CLASSLOADER); + if (LOG.isDebugEnabled()) + LOG.debug("Core classloader = {}", coreLoader); + + //provide access to all ee9 classes + ClassLoader environmentLoader = new OSGiClassLoader(coreLoader, _myBundle); + if (LOG.isDebugEnabled()) + LOG.debug("Environment classloader = {}", environmentLoader); + + //Ensure Configurations.getKnown is called with a classloader that can see all of the ee9 and core classes + + ClassLoader old = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(environmentLoader); + WebAppClassLoader.runWithServerClassAccess(() -> + { + Configurations.getKnown(); + return null; + }); + } + finally + { + Thread.currentThread().setContextClassLoader(old); + } + + webApp.setConfigurations(Configurations.getKnown().stream() + .filter(c -> c.isEnabledByDefault()) + .toArray(Configuration[]::new)); + + //Make a webapp classloader + OSGiWebappClassLoader webAppLoader = new OSGiWebappClassLoader(environmentLoader, webApp, osgiApp.getBundle()); + + //Handle Require-TldBundle + //This is a comma separated list of names of bundles that contain tlds that this webapp uses. + //We add them to the webapp classloader. + String requireTldBundles = (String)osgiApp.getProperties().get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); + List pathsToTldBundles = Util.getPathsToBundlesBySymbolicNames(requireTldBundles, osgiApp.getBundle().getBundleContext()); + for (Path p : pathsToTldBundles) + webAppLoader.addClassPath(p.toUri().toString()); + + //Set up configuration from manifest headers + //extra classpath + String extraClasspath = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH); + if (extraClasspath != null) + webApp.setExtraClasspath(extraClasspath); + + webApp.setClassLoader(webAppLoader); + + //Take care of extra provider properties + webApp.setAttribute(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN, provider.getProperties().get(OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN)); + + //TODO needed? + webApp.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundles); + + //Set up some attributes + // rfc66 + webApp.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT, osgiApp.getBundle().getBundleContext()); + + // spring-dm-1.2.1 looks for the BundleContext as a different attribute. + // not a spec... but if we want to support + // org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext + // then we need to do this to: + webApp.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), osgiApp.getBundle().getBundleContext()); + + // also pass the bundle directly. sometimes a bundle does not have a + // bundlecontext. + // it is still useful to have access to the Bundle from the servlet + // context. + webApp.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, osgiApp.getBundle()); + + + // apply any META-INF/context.xml file that is found to configure + // the webapp first + //First try looking for one in /META-INF + URI tmpUri = null; + + URL contextXmlURL = Util.getLocalizedEntry("/META-INF/jetty-webapp-context.xml", osgiApp.getBundle()); + if (contextXmlURL != null) + tmpUri = contextXmlURL.toURI(); + + //Then look in the property OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH and apply the first one + if (contextXmlURL == null) + { + String tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); + if (tmp != null) + { + String[] filenames = tmp.split("[,;]"); + tmpUri = Util.resolvePathAsLocalizedURI(filenames[0], osgiApp.getBundle(), jettyHomePath); + } + } + + //apply a context xml if there is one + if (tmpUri != null) + { + final URI contextXmlUri = tmpUri; + ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(webApp.getClassLoader()); + WebAppClassLoader.runWithServerClassAccess(() -> + { + XmlConfiguration xmlConfiguration = new XmlConfiguration(ResourceFactory.of(webApp).newResource(contextXmlUri)); + WebAppClassLoader.runWithServerClassAccess(() -> + { + Map properties = new HashMap<>(); + xmlConfiguration.getIdMap().put("Server", osgiApp.getDeploymentManager().getServer()); + properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, osgiApp.getPath().toUri().toString()); + properties.put(OSGiServerConstants.JETTY_HOME, (String)osgiApp.getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME)); + xmlConfiguration.getProperties().putAll(properties); + xmlConfiguration.configure(webApp); + return null; + }); + return null; + }); + } + catch (Exception e) + { + LOG.warn("Error applying context xml", e); + throw e; + } + finally + { + Thread.currentThread().setContextClassLoader(oldLoader); + } + } + + //ensure the context path is set + webApp.setContextPath(osgiApp.getContextPath()); + + //osgi Enterprise Spec r4 p.427 + webApp.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, osgiApp.getBundle().getBundleContext()); + + //Indicate the webapp has been deployed, so that we don't try and redeploy again + webApp.setAttribute(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK); + + //make sure we protect also the osgi dirs specified by OSGi Enterprise spec + String[] targets = webApp.getProtectedTargets(); + String[] updatedTargets = null; + if (targets != null) + { + updatedTargets = new String[targets.length + OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(targets, 0, updatedTargets, 0, targets.length); + } + else + updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length]; + System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, targets.length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length); + webApp.setProtectedTargets(updatedTargets); + + + Path bundlePath = osgiApp.getPath(); + + Resource bundleResource = osgiApp.getBundleResource(); + + String pathToResourceBase = osgiApp.getPathToResourceBase(); + + //if the path wasn't set or it was ., then it is the root of the bundle's installed location + if (StringUtil.isBlank(pathToResourceBase) || ".".equals(pathToResourceBase)) + { + if (LOG.isDebugEnabled()) + LOG.debug("Webapp base using bundle install location: {}", bundleResource); + webApp.setWarResource(bundleResource); + } + else + { + if (pathToResourceBase.startsWith("/") || pathToResourceBase.startsWith("file:")) + { + //The baseResource is outside of the bundle + Path p = Paths.get(pathToResourceBase); + webApp.setWar(p.toUri().toString()); + if (LOG.isDebugEnabled()) + LOG.debug("Webapp base using absolute location: {}", p); + } + else + { + //The baseResource is relative to the root of the bundle + Resource r = bundleResource.resolve(pathToResourceBase); + webApp.setWarResource(r); + if (LOG.isDebugEnabled()) + LOG.debug("Webapp base using path relative to bundle unpacked install location: {}", r); + } + } + + //web.xml + String tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_WEB_XML_PATH); + if (!StringUtil.isBlank(tmp)) + { + URI webXml = Util.resolvePathAsLocalizedURI(tmp, osgiApp.getBundle(), jettyHomePath); + if (webXml != null) + webApp.setDescriptor(webXml.toString()); + } + + // webdefault-ee9.xml + tmp = osgiApp.getProperties().get(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH); + if (tmp != null) + { + URI defaultWebXml = Util.resolvePathAsLocalizedURI(tmp, osgiApp.getBundle(), jettyHomePath); + if (defaultWebXml != null) + { + webApp.setDefaultsDescriptor(defaultWebXml.toString()); + } + } + + return webApp.getCoreContextHandler(); + } + } + + private PackageAdminServiceTracker _packageAdminServiceTracker; + private ServiceTracker _tracker; + + /** + * Track jetty Server instances and add ability to deploy EE9 contexts/webapps + * + * @param context the bundle context + */ + @Override + public void start(final BundleContext context) throws Exception + { + // track other bundles and fragments attached to this bundle that we + // should activate. + _packageAdminServiceTracker = new PackageAdminServiceTracker(context); + + //track jetty Server instances + _tracker = new ServiceTracker(context, context.createFilter("(objectclass=" + Server.class.getName() + ")"), new ServerTracker(context.getBundle())); + _tracker.open(); + + //register for bundleresource: url resource handling + ResourceFactory.registerResourceFactory("bundleresource", new URLResourceFactory()); + } + + /** + * Stop the activator. + * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception + { + if (_tracker != null) + { + _tracker.close(); + _tracker = null; + } + } +} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/JettyBootstrapActivator.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/JettyBootstrapActivator.java deleted file mode 100644 index 46540530def..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/JettyBootstrapActivator.java +++ /dev/null @@ -1,126 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.JettyServerServiceTracker; -import org.eclipse.jetty.ee9.osgi.boot.utils.internal.PackageAdminServiceTracker; -import org.eclipse.jetty.server.Server; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JettyBootstrapActivator - *

- * Bootstrap jetty and publish a default Server instance as an OSGi service. - *

- * Listen for other Server instances to be published as services and support them as deployment targets. - *

- * Listen for Bundles to be activated, and deploy those that represent webapps/ContextHandlers to one of the known Server instances. - */ -public class JettyBootstrapActivator implements BundleActivator -{ - private static final Logger LOG = LoggerFactory.getLogger(JettyBootstrapActivator.class); - - private static JettyBootstrapActivator INSTANCE = null; - - public static JettyBootstrapActivator getInstance() - { - return INSTANCE; - } - - private ServiceRegistration _registeredServer; - - private PackageAdminServiceTracker _packageAdminServiceTracker; - - private ServiceTracker _jettyServerServiceTracker; - - /** - * Setup a new jetty Server, registers it as a service. Setup the Service - * tracker for the jetty ContextHandlers that are in charge of deploying the - * webapps. Setup the BundleListener that supports the extender pattern for - * the jetty ContextHandler. - * - * @param context the bundle context - */ - @Override - public void start(final BundleContext context) throws Exception - { - ServiceReference[] references = context.getAllServiceReferences("org.eclipse.jetty.http.HttpFieldPreEncoder", null); - - if (references == null || references.length == 0) - LOG.warn("OSGi support for java.util.ServiceLoader may not be present. You may experience runtime errors."); - - INSTANCE = this; - - // track other bundles and fragments attached to this bundle that we - // should activate. - _packageAdminServiceTracker = new PackageAdminServiceTracker(context); - - // track jetty Server instances that we should support as deployment targets - _jettyServerServiceTracker = new ServiceTracker(context, context.createFilter("(objectclass=" + Server.class.getName() + ")"), new JettyServerServiceTracker()); - _jettyServerServiceTracker.open(); - - // Create a default jetty instance right now. - DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context); - } - - /** - * Stop the activator. - * - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception - { - try - { - if (_jettyServerServiceTracker != null) - { - _jettyServerServiceTracker.close(); - _jettyServerServiceTracker = null; - } - if (_packageAdminServiceTracker != null) - { - _packageAdminServiceTracker.stop(); - context.removeServiceListener(_packageAdminServiceTracker); - _packageAdminServiceTracker = null; - } - if (_registeredServer != null) - { - try - { - _registeredServer.unregister(); - } - catch (IllegalArgumentException ill) - { - // already unregistered. - } - finally - { - _registeredServer = null; - } - } - } - finally - { - INSTANCE = null; - } - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiMetaInfConfiguration.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiMetaInfConfiguration.java index 106069d9df1..6541176a397 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiMetaInfConfiguration.java +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiMetaInfConfiguration.java @@ -27,34 +27,34 @@ import java.util.StringTokenizer; import java.util.TreeMap; import java.util.regex.Pattern; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee9.osgi.boot.utils.Util; -import org.eclipse.jetty.ee9.osgi.boot.utils.internal.PackageAdminServiceTracker; import org.eclipse.jetty.ee9.webapp.Configuration; import org.eclipse.jetty.ee9.webapp.MetaInfConfiguration; import org.eclipse.jetty.ee9.webapp.WebAppContext; -import org.eclipse.jetty.ee9.webapp.WebInfConfiguration; +import org.eclipse.jetty.osgi.OSGiWebappConstants; +import org.eclipse.jetty.osgi.util.BundleFileLocatorHelperFactory; +import org.eclipse.jetty.osgi.util.Util; +import org.eclipse.jetty.util.FileID; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.ResourceCollection; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * OSGiWebInfConfiguration + * OSGiMetaInfConfiguration * - * Handle adding resources found in bundle fragments, and add them into the + * Handle adding resources found in bundles. */ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { - private static final Logger LOG = LoggerFactory.getLogger(WebInfConfiguration.class); + private static final Logger LOG = LoggerFactory.getLogger(OSGiMetaInfConfiguration.class); /** * Comma separated list of symbolic names of bundles that contain tlds that should be considered * as on the container classpath */ - public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.ee9.osgi.tldbundles"; + public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles"; /** * Regex of symbolic names of bundles that should be considered to be on the container classpath */ @@ -108,28 +108,30 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration names.add(tokenizer.nextToken()); } } - HashSet matchingResources = new HashSet(); + + HashSet matchingResources = new HashSet<>(); if (!names.isEmpty() || pattern != null) { Bundle[] bundles = FrameworkUtil.getBundle(OSGiMetaInfConfiguration.class).getBundleContext().getBundles(); for (Bundle bundle : bundles) { - LOG.debug("Checking bundle {}:{}", bundle.getBundleId(), bundle.getSymbolicName()); + if (LOG.isDebugEnabled()) + LOG.debug("Checking bundle {}:{}", bundle.getBundleId(), bundle.getSymbolicName()); if (pattern != null) { // if bundle symbolic name matches the pattern if (pattern.matcher(bundle.getSymbolicName()).matches()) { //get the file location of the jar and put it into the list of container jars that will be scanned for stuff (including tlds) - matchingResources.addAll(getBundleAsResource(bundle)); + matchingResources.addAll(getBundleAsResource(ResourceFactory.of(context), bundle)); } } if (names != null) { //if there is an explicit bundle name, then check if it matches if (names.contains(bundle.getSymbolicName())) - matchingResources.addAll(getBundleAsResource(bundle)); + matchingResources.addAll(getBundleAsResource(ResourceFactory.of(context), bundle)); } } } @@ -168,6 +170,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration Bundle[] bundles = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles((Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE)); if (bundles != null && bundles.length > 0) { + @SuppressWarnings("unchecked") Set fragsAndReqsBundles = (Set)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES); if (fragsAndReqsBundles == null) { @@ -175,6 +178,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, fragsAndReqsBundles); } + @SuppressWarnings("unchecked") Set fragsAndReqsResources = (Set)context.getAttribute(FRAGMENT_AND_REQUIRED_RESOURCES); if (fragsAndReqsResources == null) { @@ -191,7 +195,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration //add to context attribute storing associated fragments and required bundles fragsAndReqsBundles.add(b); File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(b); - Resource r = Resource.newResource(f.toURI()); + Resource r = ResourceFactory.of(context).newResource(f.toURI()); //add to convenience context attribute storing fragments and required bundles as Resources fragsAndReqsResources.add(r); mergedResources.add(r); @@ -217,6 +221,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE); if (bundle != null) { + @SuppressWarnings("unchecked") Set fragments = (Set)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES); if (fragments != null && !fragments.isEmpty()) { @@ -236,14 +241,15 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration for (Bundle frag : fragments) { String path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_FRAGMENT_RESOURCE_PATH, frag.getHeaders()); - convertFragmentPathToResource(path, frag, appendedResourcesPath); + convertFragmentPathToResource(ResourceFactory.of(context), path, frag, appendedResourcesPath); path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_PREPEND_FRAGMENT_RESOURCE_PATH, frag.getHeaders()); - convertFragmentPathToResource(path, frag, prependedResourcesPath); + convertFragmentPathToResource(ResourceFactory.of(context), path, frag, prependedResourcesPath); } if (!appendedResourcesPath.isEmpty()) { - LinkedHashSet resources = new LinkedHashSet(); + LinkedHashSet resources = new LinkedHashSet<>(); //Add in any existing setting of extra resource dirs + @SuppressWarnings("unchecked") Set resourceDirs = (Set)context.getAttribute(MetaInfConfiguration.RESOURCE_DIRS); if (resourceDirs != null && !resourceDirs.isEmpty()) resources.addAll(resourceDirs); @@ -263,7 +269,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration Resource[] resources = new Resource[1 + prependedResourcesPath.size()]; System.arraycopy(prependedResourcesPath.values().toArray(new Resource[prependedResourcesPath.size()]), 0, resources, 0, prependedResourcesPath.size()); resources[resources.length - 1] = context.getBaseResource(); - context.setBaseResource(Resource.of(resources)); + context.setBaseResource(ResourceFactory.combine(resources)); } } @@ -271,10 +277,10 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration * Resolves the bundle. Usually that would be a single URL per bundle. But we do some more work if there are jars * embedded in the bundle. */ - private List getBundleAsResource(Bundle bundle) + private List getBundleAsResource(ResourceFactory resourceFactory, Bundle bundle) throws Exception { - List resources = new ArrayList(); + List resources = new ArrayList<>(); File file = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); if (file.isDirectory()) @@ -283,7 +289,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { if (FileID.isJavaArchive(f.getName()) && f.isFile()) { - resources.add(Resource.newResource(f)); + resources.add(resourceFactory.newResource(f.toPath())); } else if (f.isDirectory() && f.getName().equals("lib")) { @@ -291,16 +297,16 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { if (FileID.isJavaArchive(f2.getName()) && f2.isFile()) { - resources.add(Resource.newResource(f)); + resources.add(resourceFactory.newResource(f.toPath())); } } } } - resources.add(Resource.newResource(file)); //TODO really??? + resources.add(resourceFactory.newResource(file.toPath())); //TODO really??? } else { - resources.add(Resource.newResource(file)); + resources.add(resourceFactory.newResource(file.toPath())); } return resources; @@ -309,7 +315,7 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration /** * Convert a path inside a fragment into a Resource */ - private void convertFragmentPathToResource(String resourcePath, Bundle fragment, Map resourceMap) + private void convertFragmentPathToResource(ResourceFactory resourceFactory, String resourcePath, Bundle fragment, Map resourceMap) throws Exception { if (resourcePath == null) @@ -332,6 +338,6 @@ public class OSGiMetaInfConfiguration extends MetaInfConfiguration { uri = new URI(url.toString().replaceAll(" ", "%20")); } - resourceMap.put(key + ";" + fragment.getSymbolicName(), Resource.newResource(uri)); + resourceMap.put(key + ";" + fragment.getSymbolicName(), resourceFactory.newResource(uri)); } } diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebInfConfiguration.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebInfConfiguration.java deleted file mode 100644 index cf10a241aa3..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebInfConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import org.eclipse.jetty.ee9.webapp.Configuration; -import org.eclipse.jetty.ee9.webapp.WebInfConfiguration; - -/** - * OSGiWebInfConfiguration - * - * Handle adding resources found in bundle fragments, and add them into the - */ -public class OSGiWebInfConfiguration extends WebInfConfiguration -{ - @Override - public Class replaces() - { - return WebInfConfiguration.class; - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/webapp/OSGiWebappClassLoader.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebappClassLoader.java similarity index 54% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/webapp/OSGiWebappClassLoader.java rename to jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebappClassLoader.java index 4fc4e71ef79..d2480b220fb 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/webapp/OSGiWebappClassLoader.java +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebappClassLoader.java @@ -11,24 +11,15 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.internal.webapp; +package org.eclipse.jetty.ee9.osgi.boot; -import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.ArrayList; import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.jar.JarFile; -import jakarta.servlet.http.HttpServlet; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleClassLoaderHelperFactory; import org.eclipse.jetty.ee9.webapp.WebAppClassLoader; import org.eclipse.jetty.ee9.webapp.WebAppContext; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.osgi.util.BundleClassLoaderHelperFactory; import org.osgi.framework.Bundle; import org.osgi.framework.BundleReference; import org.slf4j.Logger; @@ -42,30 +33,8 @@ import org.slf4j.LoggerFactory; */ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleReference { - private static final Logger LOG = LoggerFactory.getLogger(OSGiWebappClassLoader.class.getName()); - /** - * when a logging framework is setup in the osgi classloaders, it can access - * this and register the classes that must not be found in the jar. - */ - public static final Set JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED = new HashSet<>(); - - public static void addClassThatIdentifiesAJarThatMustBeRejected(Class zclass) - { - JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(TypeUtil.toClassReference(zclass.getName())); - } - - public static void addClassThatIdentifiesAJarThatMustBeRejected(String zclassName) - { - JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED.add(TypeUtil.toClassReference(zclassName)); - } - - static - { - addClassThatIdentifiesAJarThatMustBeRejected(HttpServlet.class); - } - private ClassLoader _osgiBundleClassLoader; private Bundle _contributor; @@ -171,91 +140,4 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe } } } - - private List toList(Enumeration e, Enumeration e2) - { - List list = new ArrayList<>(); - while (e != null && e.hasMoreElements()) - { - list.add(e.nextElement()); - } - while (e2 != null && e2.hasMoreElements()) - { - list.add(e2.nextElement()); - } - return list; - } - - /** - * Parse the classpath ourselves to be able to filter things. This is a - * derivative work of the super class - */ - @Override - public void addClassPath(String classPath) throws IOException - { - for (Resource resource : Resource.fromList(classPath, false, (path) -> getContext().newResource(path))) - { - File file = resource.getFile(); - if (file != null && isAcceptableLibrary(file, JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED)) - { - super.addClassPath(resource); - } - else - { - LOG.info("Did not add {} to the classloader of the webapp {}", resource, getContext()); - } - } - } - - /** - * @return true if the lib should be included in the webapp classloader. - */ - private boolean isAcceptableLibrary(File file, Set pathToClassFiles) - { - try - { - if (file.isDirectory()) - { - for (String criteria : pathToClassFiles) - { - if (new File(file, criteria).exists()) - { - return false; - } - } - } - else - { - JarFile jar = null; - try - { - jar = new JarFile(file); - for (String criteria : pathToClassFiles) - { - if (jar.getEntry(criteria) != null) - { - return false; - } - } - } - finally - { - if (jar != null) - try - { - jar.close(); - } - catch (IOException ignored) - { - } - } - } - } - catch (IOException e) - { - // nevermind. just trying our best - LOG.trace("IGNORED", e); - } - return true; - } } diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/PackageAdminServiceTracker.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/PackageAdminServiceTracker.java similarity index 99% rename from jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/PackageAdminServiceTracker.java rename to jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/PackageAdminServiceTracker.java index 2577fc06447..2f5e1a0197f 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/internal/PackageAdminServiceTracker.java +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/PackageAdminServiceTracker.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee9.osgi.boot.utils.internal; +package org.eclipse.jetty.ee9.osgi.boot; import java.util.ArrayList; import java.util.LinkedHashMap; diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceContextProvider.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceContextProvider.java deleted file mode 100644 index 20f14d9f472..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceContextProvider.java +++ /dev/null @@ -1,224 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee9.osgi.boot.utils.Util; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.Filter; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ServiceContextProvider - * - * Jetty DeploymentManager Provider that is able to deploy ContextHandlers discovered via OSGi as services. - */ -public class ServiceContextProvider extends AbstractContextProvider implements ServiceProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); - - private Map _serviceMap = new HashMap<>(); - - private ServiceRegistration _serviceRegForServices; - - ServiceTracker _tracker; - - /** - * ContextTracker - */ - public class ContextTracker extends ServiceTracker - { - - public ContextTracker(BundleContext bundleContext, Filter filter) - { - super(bundleContext, filter, null); - } - - @Override - public Object addingService(ServiceReference reference) - { - ContextHandler h = (ContextHandler)context.getService(reference); - serviceAdded(reference, h); - return h; - } - - @Override - public void modifiedService(ServiceReference reference, Object service) - { - removedService(reference, service); - addingService(reference); - } - - @Override - public void removedService(ServiceReference reference, Object service) - { - context.ungetService(reference); - serviceRemoved(reference, (ContextHandler)service); - } - } - - /** - * ServiceApp - */ - public class ServiceApp extends OSGiApp - { - public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String contextFile, String originId) - { - super(manager, provider, bundle, properties, contextFile, originId); - } - - public ServiceApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile) - { - super(manager, provider, originId, bundle, contextFile); - } - - @Override - public void registerAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - - @Override - protected void deregisterAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - } - - public ServiceContextProvider(ServerInstanceWrapper wrapper) - { - super(wrapper); - } - - @Override - public boolean serviceAdded(ServiceReference serviceRef, ContextHandler context) - { - if (context == null || serviceRef == null) - return false; - - if (context instanceof org.eclipse.jetty.ee9.webapp.WebAppContext) - return false; //the ServiceWebAppProvider will deploy it - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a contexthandler that has already been registered as a service by another of our deployers - - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps()); - try - { - //See if there is a context file to apply to this pre-made context - String contextFile = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH); - - String[] keys = serviceRef.getPropertyKeys(); - Dictionary properties = new Hashtable<>(); - if (keys != null) - { - for (String key : keys) - { - properties.put(key, serviceRef.getProperty(key)); - } - } - Bundle bundle = serviceRef.getBundle(); - String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-" + (contextFile != null ? contextFile : serviceRef.getProperty(Constants.SERVICE_ID)); - ServiceApp app = new ServiceApp(getDeploymentManager(), this, bundle, properties, contextFile, originId); - app.setHandler(context); //set the pre=made ContextHandler instance - _serviceMap.put(serviceRef, app); - getDeploymentManager().addApp(app); - return true; - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - - @Override - public boolean serviceRemoved(ServiceReference serviceRef, ContextHandler context) - { - - if (context == null || serviceRef == null) - return false; - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a contexthandler that will be deregistered as a service by another of our deployers - - App app = _serviceMap.remove(serviceRef); - if (app != null) - { - getDeploymentManager().removeApp(app); - return true; - } - - return false; - } - - @Override - protected void doStart() throws Exception - { - - BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); - - //Start a tracker to find webapps that are osgi services that are targeted to my server name - _tracker = new ContextTracker(bundleContext, - Util.createFilter(bundleContext, ContextHandler.class.getName(), getServerInstanceWrapper().getManagedServerName())); - _tracker.open(); - - //register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to - Dictionary properties = new Hashtable<>(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); - - //register as an osgi service for deploying contexts, advertising the name of the jetty Server instance we are related to - _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties); - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - if (_tracker != null) - _tracker.close(); - - //unregister ourselves - if (_serviceRegForServices != null) - { - try - { - _serviceRegForServices.unregister(); - } - catch (Exception e) - { - LOG.warn("Unable to unregister {}", _serviceRegForServices, e); - } - } - super.doStop(); - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceWebAppProvider.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceWebAppProvider.java deleted file mode 100644 index b702d50ede9..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/ServiceWebAppProvider.java +++ /dev/null @@ -1,256 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot; - -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.eclipse.jetty.deploy.App; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory.ServerInstanceWrapper; -import org.eclipse.jetty.ee9.osgi.boot.utils.Util; -import org.eclipse.jetty.ee9.webapp.WebAppContext; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Filter; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.ServiceTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ServiceWebAppProvider - *

- * Jetty Provider that knows how to deploy a WebApp that has been registered as an OSGi service. - */ -public class ServiceWebAppProvider extends AbstractWebAppProvider implements ServiceProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractWebAppProvider.class); - - /** - * Map of ServiceRef to App. Used when it is an osgi service that is a WebAppContext. - */ - private Map _serviceMap = new HashMap<>(); - - private ServiceRegistration _serviceRegForServices; - - private ServiceTracker webappTracker; - - /** - * WebAppTracker - */ - public class WebAppTracker extends ServiceTracker - { - /** - * @param bundleContext the osgi context - * @param filter the osgi filter for the tracker - */ - public WebAppTracker(BundleContext bundleContext, Filter filter) - { - super(bundleContext, filter, null); - } - - @Override - public Object addingService(ServiceReference reference) - { - WebAppContext wac = (WebAppContext)context.getService(reference); - serviceAdded(reference, wac); - return wac; - } - - @Override - public void modifiedService(ServiceReference reference, Object service) - { - removedService(reference, service); - addingService(reference); - } - - @Override - public void removedService(ServiceReference reference, Object service) - { - serviceRemoved(reference, (WebAppContext)service); - context.ungetService(reference); - } - } - - /** - * ServiceApp - */ - public class ServiceApp extends OSGiApp - { - - public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId) - { - super(manager, provider, bundle, properties, originId); - } - - public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId) - { - super(manager, provider, bundle, originId); - } - - @Override - public void registerAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - - @Override - protected void deregisterAsOSGiService() throws Exception - { - //not applicable for apps that are already services - } - } - - public ServiceWebAppProvider(ServerInstanceWrapper wrapper) - { - super(wrapper); - } - - /** - * A webapp that was deployed as an osgi service has been added, - * and we want to deploy it. - * - * @param context the webapp - */ - @Override - public boolean serviceAdded(ServiceReference serviceRef, ContextHandler context) - { - if (context == null || !(context instanceof WebAppContext)) - return false; - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a webapp that has already been registered as a service by another of our deployers - - WebAppContext webApp = (WebAppContext)context; - Dictionary properties = new Hashtable<>(); - - String contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); - if (contextPath == null) - return false; //No context path - - String base = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH); - - if (base == null) - return false; //No webapp base - - String webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH); - if (webdefaultXml != null) - properties.put(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH, webdefaultXml); - - String webXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WEB_XML_PATH); - if (webXml != null) - properties.put(OSGiWebappConstants.JETTY_WEB_XML_PATH, webXml); - - String extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH); - if (extraClassPath != null) - properties.put(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH, extraClassPath); - - String bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); - if (bundleInstallOverride != null) - properties.put(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE, bundleInstallOverride); - - String requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); - if (requiredTlds == null) - requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE); - if (requiredTlds != null) - properties.put(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requiredTlds); - - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps()); - try - { - String originId = getOriginId(serviceRef.getBundle(), base); - ServiceApp app = new ServiceApp(getDeploymentManager(), this, serviceRef.getBundle(), properties, originId); - app.setContextPath(contextPath); - app.setWebAppPath(base); - app.setWebAppContext(webApp); //set the pre=made webapp instance - _serviceMap.put(serviceRef, app); - getDeploymentManager().addApp(app); - return true; - } - finally - { - Thread.currentThread().setContextClassLoader(cl); - } - } - - /** - * @param context the webapp - */ - @Override - public boolean serviceRemoved(ServiceReference serviceRef, ContextHandler context) - { - if (context == null || !(context instanceof WebAppContext)) - return false; - - String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); - if (watermark != null && !"".equals(watermark)) - return false; //this service represents a contexthandler that will be deregistered as a service by another of our deployers - - App app = _serviceMap.remove(serviceRef); - if (app != null) - { - getDeploymentManager().removeApp(app); - return true; - } - return false; - } - - @Override - protected void doStart() throws Exception - { - BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); - - //Start a tracker to find webapps that are osgi services that are targeted to my server name - webappTracker = new WebAppTracker(bundleContext, - Util.createFilter(bundleContext, WebAppContext.class.getName(), getServerInstanceWrapper().getManagedServerName())); - webappTracker.open(); - - //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to - Dictionary properties = new Hashtable<>(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); - - //register as an osgi service for deploying contexts (discovered as osgi services), advertising the name of the jetty Server instance we are related to - _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties); - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - webappTracker.close(); - - //unregister ourselves - if (_serviceRegForServices != null) - { - try - { - _serviceRegForServices.unregister(); - } - catch (Exception e) - { - LOG.warn("Unable to unregister {}", _serviceRegForServices, e); - } - } - super.doStop(); - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java deleted file mode 100644 index 710c0733373..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ /dev/null @@ -1,334 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -import org.eclipse.jetty.ee9.osgi.boot.JettyBootstrapActivator; -import org.eclipse.jetty.ee9.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee9.osgi.boot.utils.OSGiClassLoader; -import org.eclipse.jetty.ee9.osgi.boot.utils.Util; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.resource.JarResource; -import org.eclipse.jetty.util.resource.Resource; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * DefaultJettyAtJettyHomeHelper - *

- * Creates a default instance of Jetty, based on the values of the - * System properties "jetty.home" or "jetty.home.bundle", one of which - * must be specified in order to create the default instance. - *

- * Called by the {@link JettyBootstrapActivator} during the starting of the - * bundle. - */ -public class DefaultJettyAtJettyHomeHelper -{ - private static final Logger LOG = LoggerFactory.getLogger(DefaultJettyAtJettyHomeHelper.class); - - /** - * contains a comma separated list of paths to the etc/jetty-*.xml files - */ - public static final String JETTY_ETC_FILES = OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS; - - /** - * Set of config files to apply to a jetty Server instance if none are supplied by SYS_PROP_JETTY_ETC_FILES - */ - public static final String DEFAULT_JETTY_ETC_FILES = "etc/jetty.xml,etc/jetty-http.xml,etc/jetty-deploy.xml"; - - /** - * Default location within bundle of a jetty home dir. - */ - public static final String DEFAULT_JETTYHOME = "/jettyhome"; - - /** - * Called by the JettyBootStrapActivator. If the system property jetty.home - * is defined and points to a folder, creates a corresponding jetty - * server. - *

- * If the system property jetty.home.bundle is defined and points to a - * bundle, look for the configuration of jetty inside that bundle. - *

- *

- * In both cases reads the system property 'jetty.etc.config.urls' to locate - * the configuration files for the deployed jetty. It is a comma separated - * list of URLs or relative paths inside the bundle or folder to the config - * files. - *

- *

- * In both cases the system properties jetty.http.host, jetty.http.port and - * jetty.ssl.port are passed to the configuration files that might use them - * as part of their properties. - *

- * - * @param bundleContext the bundle context - * @return the configured server - * @throws Exception if unable to create / configure / or start the server - */ - public static Server startJettyAtJettyHome(BundleContext bundleContext) throws Exception - { - String jettyHomeSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME); - String jettyHomeBundleSysProp = System.getProperty(OSGiServerConstants.JETTY_HOME_BUNDLE); - File jettyHomeDir = null; - Bundle jettyHomeBundle = null; - - Dictionary properties = new Hashtable<>(); - if (jettyHomeSysProp != null) - { - jettyHomeSysProp = Util.resolvePropertyValue(jettyHomeSysProp); - // bug 329621 - if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) - jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1); - - if (jettyHomeBundleSysProp != null) - LOG.warn("Both jetty.home and jetty.home.bundle property defined: jetty.home.bundle ignored."); - - jettyHomeDir = new File(jettyHomeSysProp); - if (!jettyHomeDir.exists() || !jettyHomeDir.isDirectory()) - { - LOG.warn("Unable to locate the jetty.home folder {}", jettyHomeSysProp); - return null; - } - - //set jetty.home - Util.setProperty(properties, OSGiServerConstants.JETTY_HOME, jettyHomeDir.getAbsolutePath()); - } - else if (jettyHomeBundleSysProp != null) - { - jettyHomeBundleSysProp = Util.resolvePropertyValue(jettyHomeBundleSysProp); - for (Bundle b : bundleContext.getBundles()) - { - if (b.getState() == Bundle.UNINSTALLED) - continue; - - if (b.getSymbolicName().equals(jettyHomeBundleSysProp)) - { - jettyHomeBundle = b; - break; - } - } - if (jettyHomeBundle == null) - { - LOG.warn("Unable to find the jetty.home.bundle named {}", jettyHomeSysProp); - return null; - } - } - - if (jettyHomeDir == null && jettyHomeBundle == null) - { - LOG.warn("No default jetty created."); - return null; - } - - //resolve the jetty xml config files - List configURLs = jettyHomeDir != null ? getJettyConfigurationURLs(jettyHomeDir) : getJettyConfigurationURLs(jettyHomeBundle, properties); - - LOG.info("Configuring the default jetty server with {}", configURLs); - String home = (String)properties.get(OSGiServerConstants.JETTY_HOME); - String base = (String)properties.get(OSGiServerConstants.JETTY_BASE); - if (base == null) - base = home; - LOG.info("JETTY.HOME={} JETTY.BASE={}", home, base); - ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); - try - { - ClassLoader cl; - if (jettyHomeBundle != null) - { - cl = new OSGiClassLoader(JettyBootstrapActivator.class.getClassLoader(), jettyHomeBundle); - } - else - { - cl = JettyBootstrapActivator.class.getClassLoader(); - } - Thread.currentThread().setContextClassLoader(cl); - - //the default server name - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); - - //Always set home and base - Util.setProperty(properties, OSGiServerConstants.JETTY_HOME, home); - Util.setProperty(properties, OSGiServerConstants.JETTY_BASE, base); - - // copy all system properties starting with "jetty." to service properties for the jetty server service. - // these will be used as xml configuration properties. - for (Map.Entry prop : System.getProperties().entrySet()) - { - if (prop.getKey() instanceof String) - { - String skey = (String)prop.getKey(); - //never copy the jetty xml config files into the properties as we pass them explicitly into - //the call to configure, also we set home and base explicitly - if (OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS.equals(skey) || - OSGiServerConstants.JETTY_HOME.equals(skey) || - OSGiServerConstants.JETTY_BASE.equals(skey)) - continue; - - if (skey.startsWith("jetty.")) - { - Util.setProperty(properties, skey, prop.getValue()); - } - } - } - - //configure the server here rather than letting the JettyServerServiceTracker do it, because we want to be able to - //configure the ThreadPool, which can only be done via the constructor, ie from within the xml configuration processing - Server server = ServerInstanceWrapper.configure(null, configURLs, properties); - - //Register the default Server instance as an OSGi service. - //The JettyServerServiceTracker will notice it and set it up to deploy bundles as wars etc - bundleContext.registerService(Server.class.getName(), server, properties); - LOG.info("Default jetty server configured"); - return server; - } - catch (Exception e) - { - LOG.warn("Failed to start Jetty at Jetty Home", e); - throw e; - } - finally - { - Thread.currentThread().setContextClassLoader(contextCl); - } - } - - /** - * Minimum setup for the location of the configuration files given a - * jettyhome folder. Reads the system property jetty.etc.config.urls and - * look for the corresponding jetty configuration files that will be used to - * setup the jetty server. - */ - private static List getJettyConfigurationURLs(File jettyhome) - throws MalformedURLException - { - List configURLs = new ArrayList<>(); - String jettyetc = System.getProperty(JETTY_ETC_FILES, DEFAULT_JETTY_ETC_FILES); - StringTokenizer tokenizer = new StringTokenizer(jettyetc, ";,", false); - while (tokenizer.hasMoreTokens()) - { - String next = tokenizer.nextToken().trim(); - //etc files can either be relative to jetty.home or absolute disk locations - if (!next.startsWith("/") && (next.indexOf(':') == -1)) - configURLs.add(new File(jettyhome, next).toURI().toURL()); - else - configURLs.add(new URL(next)); - } - return configURLs; - } - - /** - * Minimum setup for the location of the configuration files given a - * configuration embedded inside a bundle. Reads the system property - * jetty.etc.config.urls and look for the corresponding jetty configuration - * files that will be used to setup the jetty server. - */ - private static List getJettyConfigurationURLs(Bundle configurationBundle, Dictionary properties) - throws Exception - { - List configURLs = new ArrayList<>(); - String files = System.getProperty(JETTY_ETC_FILES, DEFAULT_JETTY_ETC_FILES); - StringTokenizer tokenizer = new StringTokenizer(files, ";,", false); - - while (tokenizer.hasMoreTokens()) - { - String etcFile = tokenizer.nextToken().trim(); - - //file path is absolute - if (etcFile.startsWith("/") || etcFile.indexOf(":") != -1) - configURLs.add(new URL(etcFile)); - else //relative file path - { - Enumeration enUrls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(configurationBundle, etcFile); - - String home = null; - // default for org.eclipse.osgi.boot where we look inside - // jettyhome/ for the default embedded configuration. - if ((enUrls == null || !enUrls.hasMoreElements())) - { - home = DEFAULT_JETTYHOME; - String tmp = DEFAULT_JETTYHOME + (DEFAULT_JETTYHOME.endsWith("/") ? "" : "/") + etcFile; - enUrls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(configurationBundle, tmp); - LOG.info("Configuring jetty from bundle: {} with {}", configurationBundle.getSymbolicName(), tmp); - } - - //lazily ensure jetty.home value is set based on location of etc files - if (properties.get(OSGiServerConstants.JETTY_HOME) == null) - { - Resource res = findDir(configurationBundle, home); - if (res != null) - properties.put(OSGiServerConstants.JETTY_HOME, res.toString()); - } - - if (enUrls == null || !enUrls.hasMoreElements()) - throw new IllegalStateException("Unable to locate a jetty configuration file for " + etcFile); - - URL url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(enUrls.nextElement()); - configURLs.add(url); - } - } - return configURLs; - } - - /** - * Get a resource representing a directory inside a bundle. If the dir is null, - * return a resource representing the installation location of the bundle. - * - * @param bundle the bundle - * @param dir the directory - * @return the resource found - */ - public static Resource findDir(Bundle bundle, String dir) - { - if (bundle == null) - return null; - - try - { - File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle); - URL u = f.toURI().toURL(); - u = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(u); - Resource res = Resource.newResource(u); - URI ruri = res.getURI(); - - //check if it is an unarchived bundle - if ("file".equalsIgnoreCase(ruri.getScheme()) && FileID.isJavaArchive(ruri)) - res = JarResource.newJarResource(res); - - //if looking for a directory - if (dir != null) - res = res.addPath(dir); - - return res; - } - catch (Exception e) - { - LOG.warn("Bad bundle location", e); - return null; - } - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java deleted file mode 100644 index f6dbdbfb9fd..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory; - -import java.util.Dictionary; -import java.util.Hashtable; - -import org.eclipse.jetty.ee9.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.server.Server; -import org.osgi.framework.Bundle; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.ServiceTrackerCustomizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JettyServerServiceTracker - * - * Tracks instances of Jetty Servers, and configures them so that they can deploy - * webapps or ContextHandlers discovered from the OSGi environment. - */ -public class JettyServerServiceTracker implements ServiceTrackerCustomizer -{ - private static Logger LOG = LoggerFactory.getLogger(JettyServerServiceTracker.class.getName()); - - @Override - public Object addingService(ServiceReference sr) - { - Bundle contributor = sr.getBundle(); - Server server = (Server)contributor.getBundleContext().getService(sr); - String name = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - if (name == null) - { - throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); - } - if (LOG.isDebugEnabled()) - LOG.debug("Adding Server {}", name); - ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name); - Dictionary props = new Hashtable<>(); - for (String key : sr.getPropertyKeys()) - { - props.put(key, sr.getProperty(key)); - } - try - { - wrapper.start(server, props); - LOG.info("Started Server {}", name); - return wrapper; - } - catch (Exception e) - { - LOG.warn("Failed to start server {}", name, e); - return sr.getBundle().getBundleContext().getService(sr); - } - } - - @Override - public void modifiedService(ServiceReference reference, Object service) - { - removedService(reference, service); - addingService(reference); - } - - @Override - public void removedService(ServiceReference reference, Object service) - { - if (service instanceof ServerInstanceWrapper) - { - ServerInstanceWrapper wrapper = (ServerInstanceWrapper)service; - try - { - wrapper.stop(); - LOG.info("Stopped Server {}", wrapper.getManagedServerName()); - } - catch (Exception e) - { - LOG.warn("Failed to stop server {}", wrapper.getManagedServerName(), e); - } - } - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java deleted file mode 100644 index 3d14ca0c564..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java +++ /dev/null @@ -1,441 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot.internal.serverfactory; - -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -import org.eclipse.jetty.deploy.AppLifeCycle; -import org.eclipse.jetty.deploy.AppProvider; -import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.deploy.bindings.StandardStarter; -import org.eclipse.jetty.deploy.bindings.StandardStopper; -import org.eclipse.jetty.ee9.osgi.boot.BundleContextProvider; -import org.eclipse.jetty.ee9.osgi.boot.BundleWebAppProvider; -import org.eclipse.jetty.ee9.osgi.boot.JettyBootstrapActivator; -import org.eclipse.jetty.ee9.osgi.boot.OSGiDeployer; -import org.eclipse.jetty.ee9.osgi.boot.OSGiServerConstants; -import org.eclipse.jetty.ee9.osgi.boot.OSGiUndeployer; -import org.eclipse.jetty.ee9.osgi.boot.ServiceContextProvider; -import org.eclipse.jetty.ee9.osgi.boot.ServiceWebAppProvider; -import org.eclipse.jetty.ee9.osgi.boot.internal.webapp.LibExtClassLoaderHelper; -import org.eclipse.jetty.ee9.osgi.boot.utils.BundleFileLocatorHelperFactory; -import org.eclipse.jetty.ee9.osgi.boot.utils.FakeURLClassLoader; -import org.eclipse.jetty.ee9.osgi.boot.utils.TldBundleDiscoverer; -import org.eclipse.jetty.ee9.osgi.boot.utils.Util; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.xml.XmlConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ServerInstanceWrapper - * - * Configures and starts a jetty Server instance. - */ -public class ServerInstanceWrapper -{ - - /** - * The value of this property points to the parent director of the jetty.xml - * configuration file currently executed. Everything is passed as a URL to - * support the case where the bundle is zipped. - */ - public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url"; - - private static Collection __containerTldBundleDiscoverers = new ArrayList<>(); - - private static final Logger LOG = LoggerFactory.getLogger(ServerInstanceWrapper.class.getName()); - - private final String _managedServerName; - - /** - * The managed jetty server - */ - private Server _server; - - private ContextHandlerCollection _ctxtCollection; - - /** - * This is the class loader that should be the parent classloader of any - * webapp classloader. It is in fact the _libExtClassLoader with a trick to - * let the TldScanner find the jars where the tld files are. - */ - private ClassLoader _commonParentClassLoaderForWebapps; - - private DeploymentManager _deploymentManager; - - public static void addContainerTldBundleDiscoverer(TldBundleDiscoverer tldBundleDiscoverer) - { - __containerTldBundleDiscoverers.add(tldBundleDiscoverer); - } - - public static Collection getContainerTldBundleDiscoverers() - { - return __containerTldBundleDiscoverers; - } - - public static Server configure(Server server, List jettyConfigurations, Dictionary props) throws Exception - { - - if (jettyConfigurations == null || jettyConfigurations.isEmpty()) - { - return server; - } - - Map idMap = new HashMap<>(); - if (server != null) - { - //Put in a mapping for the id "Server" and the name of the server as the instance being configured - idMap.put("Server", server); - idMap.put((String)props.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME), server); - } - - Map properties = new HashMap<>(); - if (props != null) - { - Enumeration en = props.keys(); - while (en.hasMoreElements()) - { - String key = en.nextElement(); - Object value = props.get(key); - properties.put(key, value.toString()); - if (server != null) - server.setAttribute(key, value); - } - } - - for (URL jettyConfiguration : jettyConfigurations) - { - try - { - // Execute a Jetty configuration file - XmlConfiguration config = new XmlConfiguration(Resource.newResource(jettyConfiguration)); - - config.getIdMap().putAll(idMap); - config.getProperties().putAll(properties); - - // #334062 compute the URL of the folder that contains the - // conf file and set it as a property so we can compute relative paths - // from it. - String urlPath = jettyConfiguration.toString(); - int lastSlash = urlPath.lastIndexOf('/'); - if (lastSlash > 4) - { - urlPath = urlPath.substring(0, lastSlash); - config.getProperties().put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath); - } - - Object o = config.configure(); - if (server == null) - server = (Server)o; - - idMap = config.getIdMap(); - } - catch (Exception e) - { - LOG.warn("Configuration error in {}", jettyConfiguration); - throw e; - } - } - - return server; - } - - public ServerInstanceWrapper(String managedServerName) - { - _managedServerName = managedServerName; - } - - public String getManagedServerName() - { - return _managedServerName; - } - - /** - * The classloader that should be the parent classloader for each webapp - * deployed on this server. - * - * @return the classloader - */ - public ClassLoader getParentClassLoaderForWebapps() - { - return _commonParentClassLoaderForWebapps; - } - - /** - * @return The deployment manager registered on this server. - */ - public DeploymentManager getDeploymentManager() - { - return _deploymentManager; - } - - /** - * @return The app provider registered on this server. - */ - public Server getServer() - { - return _server; - } - - /** - * @return The collection of context handlers - */ - public ContextHandlerCollection getContextHandlerCollection() - { - return _ctxtCollection; - } - - public void start(Server server, Dictionary props) throws Exception - { - _server = server; - ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); - try - { - List sharedURLs = getManagedJettySharedLibFolderUrls(props); - - // passing this bundle's classloader as the context classloader - // makes sure there is access to all the jetty's bundles - ClassLoader libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(null, sharedURLs, JettyBootstrapActivator.class.getClassLoader()); - - if (LOG.isDebugEnabled()) - LOG.debug("LibExtClassLoader = {}", libExtClassLoader); - - Thread.currentThread().setContextClassLoader(libExtClassLoader); - - String jettyConfigurationUrls = (String)props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS); - List jettyConfigurations = jettyConfigurationUrls != null ? Util.fileNamesAsURLs(jettyConfigurationUrls, StringUtil.DEFAULT_DELIMS) : null; - - _server = configure(server, jettyConfigurations, props); - - init(); - - //if support for jsp is enabled, we need to convert locations of bundles that contain tlds into urls. - //these are tlds that we want jasper to treat as if they are on the container's classpath. Web bundles - //can use the Require-TldBundle MANIFEST header to name other tld-containing bundles that should be regarded - //as on the webapp classpath. - if (!__containerTldBundleDiscoverers.isEmpty()) - { - Set urls = new HashSet<>(); - //discover bundles with tlds that need to be on the container's classpath as URLs - for (TldBundleDiscoverer d : __containerTldBundleDiscoverers) - { - URL[] list = d.getUrlsForBundlesWithTlds(_deploymentManager, BundleFileLocatorHelperFactory.getFactory().getHelper()); - if (list != null) - { - for (URL u : list) - { - urls.add(u); - } - } - } - _commonParentClassLoaderForWebapps = new FakeURLClassLoader(libExtClassLoader, urls.toArray(new URL[urls.size()])); - } - else - _commonParentClassLoaderForWebapps = libExtClassLoader; - - if (LOG.isDebugEnabled()) - LOG.debug("common classloader = {}", _commonParentClassLoaderForWebapps); - - server.start(); - } - catch (Exception e) - { - if (server != null) - { - try - { - server.stop(); - } - catch (Exception x) - { - LOG.trace("IGNORED", x); - } - } - throw e; - } - finally - { - Thread.currentThread().setContextClassLoader(contextCl); - } - } - - public void stop() - { - try - { - if (_server.isRunning()) - { - _server.stop(); - } - } - catch (Exception e) - { - LOG.warn("Failed to stop server", e); - } - } - - /** - * Must be called after the server is configured. - * - * It is assumed the server has already been configured with the ContextHandlerCollection structure. - */ - private void init() - { - // Get the context handler - _ctxtCollection = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class); - - if (_ctxtCollection == null) - throw new IllegalStateException("ERROR: No ContextHandlerCollection configured in Server"); - - List providerClassNames = new ArrayList<>(); - - // get a deployerManager and some providers - Collection deployers = _server.getBeans(DeploymentManager.class); - if (deployers != null && !deployers.isEmpty()) - { - _deploymentManager = deployers.iterator().next(); - - for (AppProvider provider : _deploymentManager.getAppProviders()) - { - providerClassNames.add(provider.getClass().getName()); - } - } - else - { - //add some kind of default - _deploymentManager = new DeploymentManager(); - _deploymentManager.setContexts(_ctxtCollection); - _server.addBean(_deploymentManager); - } - - _deploymentManager.setUseStandardBindings(false); - List deploymentLifeCycleBindings = new ArrayList<>(); - deploymentLifeCycleBindings.add(new OSGiDeployer(this)); - deploymentLifeCycleBindings.add(new StandardStarter()); - deploymentLifeCycleBindings.add(new StandardStopper()); - deploymentLifeCycleBindings.add(new OSGiUndeployer(this)); - _deploymentManager.setLifeCycleBindings(deploymentLifeCycleBindings); - - if (!providerClassNames.contains(BundleWebAppProvider.class.getName())) - { - // create it on the fly with reasonable default values. - try - { - BundleWebAppProvider webAppProvider = new BundleWebAppProvider(this); - _deploymentManager.addAppProvider(webAppProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add BundleAppProvider to DeploymentManager", e); - } - } - - if (!providerClassNames.contains(ServiceWebAppProvider.class.getName())) - { - // create it on the fly with reasonable default values. - try - { - ServiceWebAppProvider webAppProvider = new ServiceWebAppProvider(this); - _deploymentManager.addAppProvider(webAppProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add ServiceWebAppProvider to DeploymentManager", e); - } - } - - if (!providerClassNames.contains(BundleContextProvider.class.getName())) - { - try - { - BundleContextProvider contextProvider = new BundleContextProvider(this); - _deploymentManager.addAppProvider(contextProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add BundleContextProvider to DeploymentManager", e); - } - } - - if (!providerClassNames.contains(ServiceContextProvider.class.getName())) - { - try - { - ServiceContextProvider contextProvider = new ServiceContextProvider(this); - _deploymentManager.addAppProvider(contextProvider); - } - catch (Exception e) - { - LOG.warn("Failed to add ServiceContextProvider to DeploymentManager", e); - } - } - } - - /** - * Get the Jetty Shared Lib Folder URLs in a form that is suitable for - * {@link LibExtClassLoaderHelper} to use. - * - * @param props the properties to look for the configuration in - * @return the list of URLs found, or null if none found - */ - private List getManagedJettySharedLibFolderUrls(Dictionary props) - { - String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); - if (StringUtil.isBlank(sharedURLs)) - { - return null; - } - - List libURLs = new ArrayList<>(); - - StringTokenizer tokenizer = new StringTokenizer(sharedURLs, StringUtil.DEFAULT_DELIMS, false); - while (tokenizer.hasMoreTokens()) - { - String tok = tokenizer.nextToken(); - try - { - URL url = new URL(tok); - url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(url); - if (url.getProtocol().equals("file")) - { - libURLs.add(new URL("jar:" + url.toExternalForm() + "!/")); - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("Unrecognized Jetty Shared Lib URL: {}", url); - } - } - catch (Throwable mfe) - { - LOG.warn("Unable to process legacy lib folder {}", tok, mfe); - } - } - return libURLs; - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/TldBundleDiscoverer.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/TldBundleDiscoverer.java deleted file mode 100644 index 8f49ddfe201..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/utils/TldBundleDiscoverer.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.boot.utils; - -import java.net.URL; - -import org.eclipse.jetty.deploy.DeploymentManager; - -/** - * TldBundleDiscoverer - * - * Convert bundles that contain tlds into URL locations for consumption by jasper. - */ -public interface TldBundleDiscoverer -{ - /** - * Find bundles that contain tlds and convert into URL references to their location. - * - * @param manager The {@link DeploymentManager} instance to use - * @param fileLocator the {@link BundleFileLocatorHelper} instance to use - * @return array of URLs representing locations of tld containing bundles - * @throws Exception In case of errors during resolving TLDs files - */ - URL[] getUrlsForBundlesWithTlds(DeploymentManager manager, BundleFileLocatorHelper fileLocator) throws Exception; -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.webapp.Configuration b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.webapp.Configuration index 3fef85aa61c..5ad35494cfb 100644 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.webapp.Configuration +++ b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/resources/META-INF/services/org.eclipse.jetty.ee9.webapp.Configuration @@ -1,2 +1,2 @@ org.eclipse.jetty.ee9.osgi.annotations.AnnotationConfiguration -org.eclipse.jetty.ee9.osgi.boot.OSGiWebInfConfiguration +org.eclipse.jetty.ee9.osgi.boot.OSGiMetaInfConfiguration diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/contexts/httpservice.xml b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/contexts/httpservice.xml deleted file mode 100644 index 4710d5cfadb..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/contexts/httpservice.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - org.eclipse.equinox.http.servlet.HttpServiceServlet - /* - 1 - - - - - - diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/pom.xml b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/pom.xml deleted file mode 100644 index df5e2625087..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/pom.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - org.eclipse.jetty.ee9.osgi - jetty-ee9-osgi-project - 12.0.0-SNAPSHOT - - 4.0.0 - jetty-ee9-osgi-httpservice - EE9 :: Jetty :: OSGi :: HttpService - Jetty OSGi HttpService bundle - - ${project.groupId}.httpservice - org.eclipse.jetty.ee9.osgi.httpservice.* - - - - org.eclipse.jetty - jetty-util - - - org.eclipse.jetty.ee9 - jetty-ee9-servlet - - - org.eclipse.equinox.http - servlet - - - org.eclipse.platform - org.eclipse.osgi - provided - - - org.eclipse.jetty.toolchain - jetty-jakarta-servlet-api - - - - - - - maven-antrun-plugin - - - process-resources - - - - - - - - - run - - - - - - org.apache.felix - maven-bundle-plugin - true - - - org.eclipse.jetty.ee9.osgi.httpservice - OSGi HttpService - contexts/httpservice.xml - - org.eclipse.jetty.server.handler;version="[10,11.0)", - org.eclipse.jetty.util.component;version="[10,11.0)", - org.eclipse.jetty.session;version="[10,11.0)", - org.eclipse.jetty.servlet;version="[10,11.0)", - org.eclipse.equinox.http.servlet, * - - <_nouses>true - - - - - - diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorHandlerHelper.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorHandlerHelper.java deleted file mode 100644 index 5f7716aa106..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorHandlerHelper.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.httpservice; - -import jakarta.servlet.http.HttpServlet; - -/** - * For jetty agnostic handling of errors issued by the HttpService. - * Pass a servlet to the method setHttpServiceErrorHandler. - * In the servlet to read the status code of the error or the message or the exception, - * use org.eclipse.jetty.server.Dispatch's constants: - * int errorCode = httpServletRequest.getAttribute(Dispatcher.ERROR_STATUS_CODE) - * for example. - */ -public class HttpServiceErrorHandlerHelper -{ - private static HttpServlet _customErrorHandler; - - public static HttpServlet getCustomErrorHandler() - { - return _customErrorHandler; - } - - public static void setHttpServiceErrorHandler(HttpServlet servlet) - { - _customErrorHandler = servlet; - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorPageErrorHandler.java b/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorPageErrorHandler.java deleted file mode 100644 index 8423d3bfa36..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-httpservice/src/main/java/org/eclipse/jetty/ee9/osgi/httpservice/HttpServiceErrorPageErrorHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.httpservice; - -import java.io.IOException; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee9.servlet.ErrorPageErrorHandler; -import org.eclipse.jetty.server.Request; - -/** - * Extended error page handler. - * Makes it easy to plug a servlet to handle errors thrown by the HttpService or - * to use Jetty's ErrorPageErrorHandler API to plug custom error pages. - */ -public class HttpServiceErrorPageErrorHandler extends ErrorPageErrorHandler -{ - - private static HttpServiceErrorPageErrorHandler INSTANCE; - - public static HttpServiceErrorPageErrorHandler getInstance() - { - return INSTANCE; - } - - public HttpServiceErrorPageErrorHandler() - { - INSTANCE = this; - } - - @Override - public void handle(String target, Request baseRequest, - HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException - { - if (HttpServiceErrorHandlerHelper.getCustomErrorHandler() != null) - { - try - { - HttpServiceErrorHandlerHelper.getCustomErrorHandler().service(request, response); - } - catch (ServletException e) - { - //well - } - } - if (!response.isCommitted()) - { - super.handle(target, baseRequest, request, response); - } - } - - @Override - protected void doStop() throws Exception - { - INSTANCE = null; - super.doStop(); - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/pom.xml b/jetty-ee9/jetty-ee9-osgi/pom.xml index 4fc9b16e372..2b04bba8ae4 100644 --- a/jetty-ee9/jetty-ee9-osgi/pom.xml +++ b/jetty-ee9/jetty-ee9-osgi/pom.xml @@ -13,6 +13,7 @@ 3.18.100 + 8.1.0 3.11.0 1.6.1 1.5.0 @@ -31,14 +32,9 @@ jetty-ee9-osgi-boot jetty-ee9-osgi-boot-jsp - jetty-ee9-osgi-boot-warurl - jetty-ee9-osgi-httpservice - test-jetty-ee9-osgi-webapp test-jetty-ee9-osgi-webapp-resources - test-jetty-ee9-osgi-context test-jetty-ee9-osgi-fragment test-jetty-ee9-osgi-server - jetty-ee9-osgi-alpn test-jetty-ee9-osgi @@ -134,6 +130,11 @@ servlet ${equinox-http-servlet-version} + + org.osgi + osgi.annotation + ${osgi-annotation-version} + diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/pom.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/pom.xml deleted file mode 100644 index a7670e1ad55..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - org.eclipse.jetty.ee9.osgi - jetty-ee9-osgi-project - 12.0.0-SNAPSHOT - - 4.0.0 - test-jetty-ee9-osgi-context - EE9 :: Jetty :: OSGi :: Test Context - Test Jetty OSGi bundle with a ContextHandler - - ${project.groupId}.testcontext - true - true - - - - org.eclipse.jetty.ee9 - jetty-ee9-nested - - - org.eclipse.platform - org.eclipse.osgi - provided - - - org.eclipse.platform - org.eclipse.osgi.services - provided - - - - - - - src/main/resources - - - src/main/context - - - - - org.apache.felix - maven-bundle-plugin - true - - - org.eclipse.jetty.ee9.osgi.testcontext;singleton:=true - Jetty OSGi Test Context - com.acme.osgi.Activator - J2SE-1.5 - - <_nouses>true - - jakarta.servlet;version="[$(version;==;${jetty.servlet.api.version}),$(version;+;${jetty.servlet.api.version}))", - jakarta.servlet.resources;version="[$(version;==;${jetty.servlet.api.version}),$(version;+;${jetty.servlet.api.version}))", - org.osgi.framework, - org.osgi.service.cm;version="${osgi-service-cm-version}", - org.osgi.service.packageadmin, - org.osgi.service.startlevel;version="1.0.0", - org.osgi.service.url;version="1.0.0", - org.osgi.util.tracker;version="${osgi-util-tracker-version}", - * - - org.eclipse.jetty.*;version="[$(version;==;${parsedVersion.osgiVersion}),$(version;+;${parsedVersion.osgiVersion}))" - - - - - - - diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/context/acme.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/context/acme.xml deleted file mode 100644 index 7f5bfe52ad8..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/context/acme.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - /unset - - - /static/ - - - - - - index.html - - - max-age=3600,public - - - - - diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/java/com/acme/osgi/Activator.java b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/java/com/acme/osgi/Activator.java deleted file mode 100644 index 6639fd4211d..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/java/com/acme/osgi/Activator.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package com.acme.osgi; - -import java.util.Dictionary; -import java.util.Hashtable; - -import jakarta.servlet.ServletContextEvent; -import jakarta.servlet.ServletContextListener; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -/** - * Bootstrap a ContextHandler - */ -public class Activator implements BundleActivator -{ - - private ServiceRegistration _sr; - - /** - * - */ - @Override - public void start(final BundleContext context) throws Exception - { - ContextHandler ch = new ContextHandler(); - ch.addEventListener(new ServletContextListener() - { - - @Override - public void contextInitialized(ServletContextEvent sce) - { - //System.err.println("Context is initialized"); - } - - @Override - public void contextDestroyed(ServletContextEvent sce) - { - //System.err.println("CONTEXT IS DESTROYED!"); - } - }); - Dictionary props = new Hashtable(); - props.put("Web-ContextPath", "/acme"); - props.put("Jetty-ContextFilePath", "acme.xml"); - _sr = context.registerService(ContextHandler.class.getName(), ch, props); - } - - /** - * Stop the activator. - * - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception - { - _sr.unregister(); - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/resources/static/index.html b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/resources/static/index.html deleted file mode 100644 index 3189646adce..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-context/src/main/resources/static/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi Context

-

ContextHandler registered as a service successfully deployed.

- - diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server/pom.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server/pom.xml index 775d343a37a..d977c10c33e 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server/pom.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server/pom.xml @@ -14,6 +14,10 @@ true
+ + org.eclipse.jetty + jetty-osgi + org.eclipse.jetty.ee9 jetty-ee9-webapp diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp-resources/pom.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp-resources/pom.xml index 5a0326be2f7..fe748b9e307 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp-resources/pom.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp-resources/pom.xml @@ -48,6 +48,7 @@ !com.acme* / + ee9
diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/pom.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/pom.xml deleted file mode 100644 index efd878f3c08..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - org.eclipse.jetty.ee9.osgi - jetty-ee9-osgi-project - 12.0.0-SNAPSHOT - ../pom.xml - - 4.0.0 - test-jetty-ee9-osgi-webapp - EE9 :: Jetty :: OSGi :: Test WebApp - Test Jetty OSGi Webapp bundle - - ${project.groupId}.webapp - true - true - - - - org.eclipse.jetty.ee9 - jetty-ee9-webapp - - - org.eclipse.platform - org.eclipse.osgi - provided - - - org.eclipse.platform - org.eclipse.osgi.services - provided - - - - - - - src/main/resources - - - - - org.apache.felix - maven-bundle-plugin - true - - - org.eclipse.jetty.ee9.osgi.testapp;singleton:=true - Jetty OSGi Test WebApp - com.acme.osgi.Activator - J2SE-1.5 - - com.acme.osgi - org.eclipse.jetty.*;version="[$(version;===;${parsedVersion.osgiVersion}),$(version;==+;${parsedVersion.osgiVersion}))" - - - - - - diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/java/com/acme/osgi/Activator.java b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/java/com/acme/osgi/Activator.java deleted file mode 100644 index bd323cdce40..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/java/com/acme/osgi/Activator.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package com.acme.osgi; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Dictionary; -import java.util.Hashtable; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee9.servlet.ServletHolder; -import org.eclipse.jetty.ee9.webapp.WebAppContext; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -/** - * Bootstrap a webapp - */ -public class Activator implements BundleActivator -{ - - private ServiceRegistration _srA; - private ServiceRegistration _srB; - - public static class TestServlet extends HttpServlet - { - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - //report the mimetype of a file - String mimetype = req.getServletContext().getMimeType("file.gz"); - resp.setContentType("text/html"); - PrintWriter writer = resp.getWriter(); - writer.write("

MIMETYPE=" + mimetype + "

"); - writer.flush(); - } - } - - /** - * - */ - @Override - public void start(BundleContext context) throws Exception - { - //Create webappA as a Service and target it at the default server - WebAppContext webapp = new WebAppContext(); - webapp.addServlet(new ServletHolder(new TestServlet()), "/mime"); - Dictionary props = new Hashtable(); - props.put("Jetty-WarResourcePath", "webappA"); - props.put("Web-ContextPath", "/acme"); - props.put("managedServerName", "defaultJettyServer"); - _srA = context.registerService(WebAppContext.class.getName(), webapp, props); - - //Create a second webappB as a Service and target it at a custom Server - //deployed by another bundle - final WebAppContext webappB = new WebAppContext(); - Dictionary propsB = new Hashtable(); - propsB.put("Jetty-WarResourcePath", "webappB"); - propsB.put("Web-ContextPath", "/acme"); - propsB.put("managedServerName", "fooServer"); - _srB = context.registerService(WebAppContext.class.getName(), webappB, propsB); - } - - /** - * Stop the activator. - * - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(BundleContext context) throws Exception - { - _srA.unregister(); - _srB.unregister(); - } -} diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/index.html b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/index.html deleted file mode 100644 index 9e62c04bb91..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi WebApp

-

Webapp registered by bundle as service successfully deployed.

- - diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappA/index.html b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappA/index.html deleted file mode 100644 index bc4c64faa54..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappA/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi WebAppA

-

Webapp registered by bundle as service successfully deployed.

- - diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappB/index.html b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappB/index.html deleted file mode 100644 index 4c6a3ae9b22..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp/src/main/resources/webappB/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - -

Test OSGi WebAppB

-

Webapp registered by bundle as service successfully deployed.

- - diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/pom.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/pom.xml index 1e178634de0..3848dcc1817 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/pom.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/pom.xml @@ -17,7 +17,7 @@ 2.6.2 1.8.3 3.0.0 - 1.3.5 + 1.3.6 1.2 true @@ -211,13 +211,6 @@ - - org.eclipse.jetty.ee9.osgi - jetty-ee9-osgi-httpservice - ${project.version} - test - - org.eclipse.jetty.toolchain jetty-jakarta-servlet-api @@ -287,6 +280,11 @@ jakarta.servlet.jsp.jstl + + org.eclipse.jetty.ee9 + jetty-ee9-jndi + runtime + org.eclipse.jetty.ee9 jetty-ee9-annotations @@ -343,32 +341,32 @@ runtime - org.eclipse.jetty.ee9 + org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-jetty-api runtime - org.eclipse.jetty.ee9 + org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-jetty-common runtime - org.eclipse.jetty.ee9 + org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-jetty-client runtime - org.eclipse.jetty.ee9 + org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-jakarta-client runtime - org.eclipse.jetty.ee9 + org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-servlet runtime - org.eclipse.jetty.ee9 + org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-jetty-server runtime @@ -378,7 +376,7 @@ runtime - org.eclipse.jetty.ee9 + org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-jakarta-server runtime @@ -390,12 +388,6 @@ org.eclipse.jetty.http2 jetty-http2-hpack - - org.eclipse.jetty.ee9.osgi - jetty-ee9-osgi-alpn - ${project.version} - test - org.eclipse.jetty jetty-alpn-server @@ -411,28 +403,28 @@ org.eclipse.jetty.ee9.demos - demo-jsp-webapp + jetty-ee9-demo-jsp-webapp ${project.version} webbundle test org.eclipse.jetty.ee9.demos - demo-jetty-webapp + jetty-ee9-demo-jetty-webapp ${project.version} webbundle test org.eclipse.jetty.ee9.demos - demo-spec-webapp + jetty-ee9-demo-spec-webapp ${project.version} war test org.eclipse.jetty.ee9.demos - demo-container-initializer + jetty-ee9-demo-container-initializer ${project.version} test @@ -457,21 +449,9 @@ org.eclipse.jetty.ee9.demos - demo-mock-resources + jetty-ee9-demo-mock-resources ${project.version} - - org.eclipse.jetty.ee9.osgi - test-jetty-ee9-osgi-context - ${project.version} - test - - - org.eclipse.jetty.ee9.osgi - test-jetty-ee9-osgi-webapp - ${project.version} - test - org.eclipse.jetty.toolchain jetty-test-helper @@ -562,6 +542,11 @@ ${env.GLOBAL_MVN_SETTINGS} -Dconscrypt-version=${conscrypt.version} + + + **/TestJettyOSGiBootHTTP2Conscrypt.java + **/TestJettyOSGiBootHTTP2JDK9.java + diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-deploy.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-deploy.xml index fe917c2430e..c6d09cb401c 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-deploy.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-deploy.xml @@ -12,10 +12,10 @@ - + diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml index cb63e130e52..75a73574423 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-context-as-service.xml @@ -33,7 +33,7 @@ - + boot.context.service.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml index 89f01444110..36b3a7d3c8a 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-webapp-as-service.xml @@ -33,7 +33,7 @@ - + boot.webapp.service.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml index 795322d5658..030a2e46832 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-annotations.xml @@ -33,7 +33,7 @@ - + boot.annotations.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml index 8cce39f8833..82f0bb0841f 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-bundle.xml @@ -33,7 +33,7 @@ - + boot.bundle.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml index a4b1cd24f12..e21afb24057 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jakarta-websocket.xml @@ -33,7 +33,7 @@ - + boot.jakarta.websocket.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml index 91751b0e24c..1b1f7b8dbb1 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-jsp.xml @@ -33,7 +33,7 @@ - + boot.jsp.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml index ea92414d31c..a1b677bc6ec 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml @@ -32,7 +32,7 @@ - + boot.resources.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml index 7201ee9ad5a..d5230f18f43 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-http-boot-with-websocket.xml @@ -33,7 +33,7 @@ - + boot.websocket.port diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml index e9ebabc4699..c5c21b3b326 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml @@ -8,12 +8,21 @@ - - - - Test Realm - /etc/realm.properties - - + + + + /etc/realm.properties + + + + + + Test Realm + + false + + + + diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty.xml index d96e0030c9c..4e8ac736b60 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty.xml @@ -64,32 +64,6 @@ - - - - - - org.eclipse.jetty.ee9.webapp.FragmentConfiguration - org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration - org.eclipse.jetty.ee9.webapp.WebXmlConfiguration - org.eclipse.jetty.ee9.webapp.WebAppConfiguration - org.eclipse.jetty.ee9.webapp.ServletsConfiguration - org.eclipse.jetty.ee9.webapp.JspConfiguration - org.eclipse.jetty.ee9.webapp.JaasConfiguration - org.eclipse.jetty.ee9.webapp.JndiConfiguration - org.eclipse.jetty.plus.webapp.PlusConfiguration - org.eclipse.jetty.plus.webapp.EnvConfiguration - org.eclipse.jetty.ee9.webapp.JmxConfiguration - org.eclipse.jetty.ee9.osgi.annotations.AnnotationConfiguration - org.eclipse.jetty.websocket.server.config.JettyWebSocketConfiguration - org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketConfiguration - org.eclipse.jetty.ee9.osgi.boot.OSGiWebInfConfiguration - org.eclipse.jetty.ee9.osgi.boot.OSGiMetaInfConfiguration - - - - - java.naming.factory.initial diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiAnnotationParser.java b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiAnnotationParser.java index da7d082d914..27f7d6585b0 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiAnnotationParser.java +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiAnnotationParser.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import aQute.bnd.osgi.Constants; import org.eclipse.jetty.ee9.annotations.ClassInheritanceHandler; import org.eclipse.jetty.ee9.osgi.annotations.AnnotationParser; +import org.eclipse.jetty.util.resource.ResourceFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; @@ -87,8 +88,8 @@ public class TestJettyOSGiAnnotationParser //test the osgi annotation parser ignore the module-info.class file in the fake bundle //Get a reference to the deployed fake bundle Bundle b = TestOSGiUtil.getBundle(bundleContext, "bundle.with.module.info"); - AnnotationParser parser = new AnnotationParser(0); - parser.indexBundle(b); + AnnotationParser parser = new AnnotationParser(); + parser.indexBundle(ResourceFactory.root(), b); ClassInheritanceHandler handler = new ClassInheritanceHandler(new ConcurrentHashMap<>()); parser.parse(Collections.singleton(handler), b); diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootContextAsService.java b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootContextAsService.java deleted file mode 100644 index ccc3369e639..00000000000 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootContextAsService.java +++ /dev/null @@ -1,114 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.osgi.test; - -import java.util.ArrayList; -import javax.inject.Inject; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.CoreOptions; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.junit.PaxExam; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.ops4j.pax.exam.CoreOptions.mavenBundle; -import static org.ops4j.pax.exam.CoreOptions.systemProperty; - -/** - * TestJettyOSGiBootContextAsService - * - * Tests deployment of a ContextHandler as an osgi Service. - * - * Tests the ServiceContextProvider. - */ -@RunWith(PaxExam.class) -public class TestJettyOSGiBootContextAsService -{ - @Inject - BundleContext bundleContext = null; - - @Configuration - public static Option[] configure() - { - ArrayList + + org.eclipse.jetty + jetty-osgi + ${project.version} + org.eclipse.jetty jetty-proxy