From 0cfd16cceb2104287a355c903205bff3d27c3a6f Mon Sep 17 00:00:00 2001 From: Manfred Baedke Date: Tue, 17 Feb 2026 14:48:17 +0100 Subject: [PATCH] JCR-4945: Ensure OSGi-enabled Jackrabbit bundles deploy in environments featuring only Slf4j v2 or even Tika v2.9 Added tests. --- .../org/apache/jackrabbit/osgi/OSGiIT.java | 1 + .../slf4j2/Slf4j_v2_Tika_v2_4_OSGiIT.java | 154 ++++++++++++++++++ .../slf4j2/Slf4j_v2_Tika_v2_9_OSGiIT.java | 154 ++++++++++++++++++ jackrabbit-it-osgi/test-bundles.xml | 1 - 4 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_4_OSGiIT.java create mode 100644 jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_9_OSGiIT.java diff --git a/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/OSGiIT.java b/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/OSGiIT.java index fb8b0f803b2..d30ac442e69 100644 --- a/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/OSGiIT.java +++ b/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/OSGiIT.java @@ -66,6 +66,7 @@ public Option[] configuration() throws IOException, URISyntaxException { mavenBundle("org.apache.felix", "org.apache.felix.fileinstall", "3.2.6"), mavenBundle("org.slf4j", "slf4j-api", "1.7.36"), mavenBundle("commons-logging", "commons-logging", "1.2"), + mavenBundle("org.apache.tika", "tika-core", "2.4.1"), mavenBundle("ch.qos.logback", "logback-core", "1.2.13"), mavenBundle("ch.qos.logback", "logback-classic", "1.2.13"), frameworkProperty("repository.home").value("target"), diff --git a/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_4_OSGiIT.java b/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_4_OSGiIT.java new file mode 100644 index 00000000000..b3371f8e328 --- /dev/null +++ b/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_4_OSGiIT.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.osgi.slf4j2; + +import static org.junit.Assert.assertEquals; +import static org.ops4j.pax.exam.CoreOptions.bundle; +import static org.ops4j.pax.exam.CoreOptions.frameworkProperty; +import static org.ops4j.pax.exam.CoreOptions.junitBundles; +import static org.ops4j.pax.exam.CoreOptions.mavenBundle; +import static org.ops4j.pax.exam.CoreOptions.systemProperties; +import static org.ops4j.pax.exam.CoreOptions.systemProperty; +import static org.ops4j.pax.exam.CoreOptions.vmOption; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.MalformedURLException; +import java.net.URISyntaxException; + +import javax.inject.Inject; + +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.ops4j.pax.exam.options.DefaultCompositeOption; +import org.ops4j.pax.exam.options.SystemPropertyOption; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerClass; +import org.ops4j.pax.exam.util.PathUtils; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.Version; + +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerClass.class) +public class Slf4j_v2_Tika_v2_4_OSGiIT { + + @Configuration + public Option[] configuration() throws IOException, URISyntaxException { + return CoreOptions.options( + junitBundles(), + mavenBundle("org.osgi", "org.osgi.service.log", "1.3.0"), + mavenBundle("org.apache.felix", "org.apache.felix.scr", "2.0.12"), + mavenBundle("org.apache.felix", "org.apache.felix.jaas", "1.0.2"), + mavenBundle("org.osgi", "org.osgi.dto", "1.0.0"), + mavenBundle("org.apache.felix", "org.apache.felix.configadmin", "1.8.16"), + mavenBundle("org.apache.felix", "org.apache.felix.fileinstall", "3.2.6"), + + //slf4j-api-2.0.7 requirement: + //[slf4j.api [24](R 24.0)] osgi.extender; (&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0))) + mavenBundle("org.ow2.asm", "asm", "9.5"), + mavenBundle("org.ow2.asm", "asm-tree", "9.5"), + mavenBundle("org.ow2.asm", "asm-analysis", "9.5"), + mavenBundle("org.ow2.asm", "asm-commons", "9.5"), + mavenBundle("org.ow2.asm", "asm-util", "9.5"), + mavenBundle("org.apache.aries.spifly", "org.apache.aries.spifly.dynamic.bundle", "1.3.6"), + + mavenBundle("org.slf4j", "slf4j-api", "2.0.7"), + mavenBundle("ch.qos.logback", "logback-core", "1.3.5"), + mavenBundle("ch.qos.logback", "logback-classic", "1.3.5"), + + mavenBundle("commons-logging", "commons-logging", "1.2"), + mavenBundle("org.apache.tika", "tika-core", "2.4.1"), + + frameworkProperty("repository.home").value("target"), + systemProperties( + systemProperty("logback.configurationFile") + .value("file:" + PathUtils.getBaseDir() + "/src/test/resources/logback-test.xml"), + new SystemPropertyOption("felix.fileinstall.dir").value(getConfigDir())), + jarBundles(), + jpmsOptions()); + } + + private Option jpmsOptions(){ + DefaultCompositeOption composite = new DefaultCompositeOption(); + if (Version.parseVersion(System.getProperty("java.specification.version")).getMajor() > 1){ + if (java.nio.file.Files.exists(java.nio.file.FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules", "java.se.ee"))){ + composite.add(vmOption("--add-modules=java.se.ee")); + } + composite.add(vmOption("--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.lang=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.lang.invoke=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.io=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.net=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.nio=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util.jar=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util.regex=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util.zip=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/sun.nio.ch=ALL-UNNAMED")); + } + return composite; + } + + private String getConfigDir(){ + return new File(new File("src", "test"), "config").getAbsolutePath(); + } + + private Option jarBundles() throws MalformedURLException { + DefaultCompositeOption composite = new DefaultCompositeOption(); + for (File bundle : new File("target", "test-bundles").listFiles()) { + if (bundle.getName().endsWith(".jar") && bundle.isFile()) { + composite.add(bundle(bundle.toURI().toURL().toString())); + } + } + return composite; + } + + @Inject + private BundleContext context; + + @Test + public void bundleStates() { + for (Bundle bundle : context.getBundles()) { + assertEquals( + String.format("Bundle %s not active. have a look at the logs", bundle.toString()), + Bundle.ACTIVE, bundle.getState()); + } + } + + @Test + public void listBundles() { + for (Bundle bundle : context.getBundles()) { + System.out.println(bundle); + } + } + + @Test + public void listServices() throws InvalidSyntaxException { + for (ServiceReference reference + : context.getAllServiceReferences(null, null)) { + System.out.println(reference); + } + } +} diff --git a/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_9_OSGiIT.java b/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_9_OSGiIT.java new file mode 100644 index 00000000000..a814892f618 --- /dev/null +++ b/jackrabbit-it-osgi/src/test/java/org/apache/jackrabbit/osgi/slf4j2/Slf4j_v2_Tika_v2_9_OSGiIT.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.osgi.slf4j2; + +import static org.junit.Assert.assertEquals; +import static org.ops4j.pax.exam.CoreOptions.bundle; +import static org.ops4j.pax.exam.CoreOptions.frameworkProperty; +import static org.ops4j.pax.exam.CoreOptions.junitBundles; +import static org.ops4j.pax.exam.CoreOptions.mavenBundle; +import static org.ops4j.pax.exam.CoreOptions.systemProperties; +import static org.ops4j.pax.exam.CoreOptions.systemProperty; +import static org.ops4j.pax.exam.CoreOptions.vmOption; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.MalformedURLException; +import java.net.URISyntaxException; + +import javax.inject.Inject; + +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.ops4j.pax.exam.options.DefaultCompositeOption; +import org.ops4j.pax.exam.options.SystemPropertyOption; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerClass; +import org.ops4j.pax.exam.util.PathUtils; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.Version; + +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerClass.class) +public class Slf4j_v2_Tika_v2_9_OSGiIT { + + @Configuration + public Option[] configuration() throws IOException, URISyntaxException { + return CoreOptions.options( + junitBundles(), + mavenBundle("org.osgi", "org.osgi.service.log", "1.3.0"), + mavenBundle("org.apache.felix", "org.apache.felix.scr", "2.0.12"), + mavenBundle("org.apache.felix", "org.apache.felix.jaas", "1.0.2"), + mavenBundle("org.osgi", "org.osgi.dto", "1.0.0"), + mavenBundle("org.apache.felix", "org.apache.felix.configadmin", "1.8.16"), + mavenBundle("org.apache.felix", "org.apache.felix.fileinstall", "3.2.6"), + + //slf4j-api-2.0.7 requirement: + //[slf4j.api [24](R 24.0)] osgi.extender; (&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0))) + mavenBundle("org.ow2.asm", "asm", "9.5"), + mavenBundle("org.ow2.asm", "asm-tree", "9.5"), + mavenBundle("org.ow2.asm", "asm-analysis", "9.5"), + mavenBundle("org.ow2.asm", "asm-commons", "9.5"), + mavenBundle("org.ow2.asm", "asm-util", "9.5"), + mavenBundle("org.apache.aries.spifly", "org.apache.aries.spifly.dynamic.bundle", "1.3.6"), + + mavenBundle("org.slf4j", "slf4j-api", "2.0.7"), + mavenBundle("ch.qos.logback", "logback-core", "1.3.5"), + mavenBundle("ch.qos.logback", "logback-classic", "1.3.5"), + + mavenBundle("commons-logging", "commons-logging", "1.2"), + mavenBundle("org.apache.tika", "tika-core", "2.9.4"), + + frameworkProperty("repository.home").value("target"), + systemProperties( + systemProperty("logback.configurationFile") + .value("file:" + PathUtils.getBaseDir() + "/src/test/resources/logback-test.xml"), + new SystemPropertyOption("felix.fileinstall.dir").value(getConfigDir())), + jarBundles(), + jpmsOptions()); + } + + private Option jpmsOptions(){ + DefaultCompositeOption composite = new DefaultCompositeOption(); + if (Version.parseVersion(System.getProperty("java.specification.version")).getMajor() > 1){ + if (java.nio.file.Files.exists(java.nio.file.FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules", "java.se.ee"))){ + composite.add(vmOption("--add-modules=java.se.ee")); + } + composite.add(vmOption("--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.lang=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.lang.invoke=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.io=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.net=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.nio=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util.jar=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util.regex=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/java.util.zip=ALL-UNNAMED")); + composite.add(vmOption("--add-opens=java.base/sun.nio.ch=ALL-UNNAMED")); + } + return composite; + } + + private String getConfigDir(){ + return new File(new File("src", "test"), "config").getAbsolutePath(); + } + + private Option jarBundles() throws MalformedURLException { + DefaultCompositeOption composite = new DefaultCompositeOption(); + for (File bundle : new File("target", "test-bundles").listFiles()) { + if (bundle.getName().endsWith(".jar") && bundle.isFile()) { + composite.add(bundle(bundle.toURI().toURL().toString())); + } + } + return composite; + } + + @Inject + private BundleContext context; + + @Test + public void bundleStates() { + for (Bundle bundle : context.getBundles()) { + assertEquals( + String.format("Bundle %s not active. have a look at the logs", bundle.toString()), + Bundle.ACTIVE, bundle.getState()); + } + } + + @Test + public void listBundles() { + for (Bundle bundle : context.getBundles()) { + System.out.println(bundle); + } + } + + @Test + public void listServices() throws InvalidSyntaxException { + for (ServiceReference reference + : context.getAllServiceReferences(null, null)) { + System.out.println(reference); + } + } +} diff --git a/jackrabbit-it-osgi/test-bundles.xml b/jackrabbit-it-osgi/test-bundles.xml index 26f9814835d..367af71f31a 100644 --- a/jackrabbit-it-osgi/test-bundles.xml +++ b/jackrabbit-it-osgi/test-bundles.xml @@ -36,7 +36,6 @@ org.apache.jackrabbit:jackrabbit-jcr-commons org.apache.jackrabbit:jackrabbit-spi org.apache.jackrabbit:jackrabbit-spi-commons - org.apache.tika:tika-core org.apache.httpcomponents:httpclient-osgi org.apache.httpcomponents:httpcore-osgi org.apache.jackrabbit:jackrabbit-webdav