Skip to content

Commit 267e21b

Browse files
authored
Support slf4j2 in OSGi (#6512)
* Make slf4j package imports dynamic, to work with org.slf4j.spi in slf4j 2 bundle. * Add slf4j 2 OSGi test. Signed-off-by: Matt Magoffin <[email protected]>
1 parent 77d0533 commit 267e21b

File tree

6 files changed

+165
-0
lines changed

6 files changed

+165
-0
lines changed

micrometer-commons/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jar {
1616
bnd '''\
1717
Import-Package: \
1818
org.aspectj.*;resolution:=dynamic,\
19+
org.slf4j.*;resolution:=dynamic,\
1920
javax.annotation.*;resolution:=optional;version="${@}",\
2021
*
2122
'''.stripIndent()

micrometer-core/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ jar {
5858
org.HdrHistogram.*;resolution:=dynamic;version="${@}",\
5959
org.apache.catalina.*;resolution:=dynamic,\
6060
org.bson.*;resolution:=dynamic;version="${@}",\
61+
org.slf4j.*;resolution:=dynamic,\
6162
rx.*;resolution:=dynamic;version="${@}",\
6263
javax.persistence.*;resolution:=dynamic;version="${@}",\
6364
io.netty.*;resolution:=dynamic;version="${@}",\
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import aQute.bnd.gradle.Bundle
2+
import aQute.bnd.gradle.Resolve
3+
import aQute.bnd.gradle.TestOSGi
4+
5+
// skip this module when building with jdk >=24
6+
// waiting for a release with the fix https://github.com/bndtools/bnd/pull/6371
7+
if (javaLanguageVersion.canCompileOrRun(24)) {
8+
project.tasks.configureEach { task -> task.enabled = false }
9+
}
10+
11+
dependencies {
12+
testImplementation libs.assertj
13+
testImplementation libs.osgiJunit5
14+
testImplementation 'org.slf4j:slf4j-api:2.0.17'
15+
testImplementation 'org.slf4j:slf4j-simple:2.0.17'
16+
17+
testImplementation project(':micrometer-core')
18+
19+
testImplementation project(':micrometer-registry-jmx')
20+
// osgi test fails when the new prometheus client is used
21+
//testImplementation project(':micrometer-registry-prometheus')
22+
testImplementation project(':micrometer-registry-prometheus-simpleclient')
23+
24+
testImplementation libs.felixFramework
25+
26+
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
27+
testRuntimeOnly libs.felixScr
28+
testRuntimeOnly 'org.slf4j:slf4j-simple:2.0.17'
29+
testRuntimeOnly 'org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle:1.3.7'
30+
}
31+
32+
def testingBundle = tasks.register('testingBundle', Bundle) {
33+
archiveClassifier = 'tests'
34+
from sourceSets.test.output
35+
if (javaLanguageVersion.asInt() < 17) {
36+
sourceSet = sourceSets.test
37+
}
38+
bundle {
39+
bnd """\
40+
Bundle-SymbolicName: \${task.archiveBaseName}-\${task.archiveClassifier}
41+
Test-Cases: \${classes;HIERARCHY_INDIRECTLY_ANNOTATED;org.junit.platform.commons.annotation.Testable;CONCRETE}
42+
""".stripIndent()
43+
}
44+
}
45+
46+
def resolveTask = tasks.register("resolve", Resolve) {
47+
dependsOn jar, testingBundle
48+
project.ext.osgiRunee="JavaSE-${javaLanguageVersion.asInt()}"
49+
bundles = files(sourceSets.test.runtimeClasspath, configurations.archives.artifacts.files)
50+
bndrun = file("test.bndrun")
51+
outputBndrun = layout.buildDirectory.file("resolved-test.bndrun")
52+
}
53+
54+
55+
56+
tasks.register("testOSGi", TestOSGi) {
57+
group = "verification"
58+
description = "Run OSGi tests"
59+
bundles = files(sourceSets.test.runtimeClasspath, configurations.archives.artifacts.files)
60+
bndrun = resolveTask.flatMap { it.outputBndrun }
61+
}
62+
63+
tasks.test.configure {
64+
actions.clear()
65+
dependsOn testOSGi
66+
}
67+
68+
artifacts {
69+
archives testingBundle
70+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2023 VMware, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.micrometer.osgi.test;
17+
18+
import io.micrometer.core.instrument.MeterRegistry;
19+
import io.micrometer.core.instrument.Metrics;
20+
import io.micrometer.core.instrument.MockClock;
21+
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
22+
import io.micrometer.jmx.JmxConfig;
23+
import io.micrometer.jmx.JmxMeterRegistry;
24+
import io.micrometer.prometheus.PrometheusConfig;
25+
import io.micrometer.prometheus.PrometheusMeterRegistry;
26+
import org.junit.jupiter.api.Test;
27+
import org.junit.jupiter.api.extension.ExtendWith;
28+
import org.osgi.framework.Bundle;
29+
import org.osgi.framework.BundleContext;
30+
import org.osgi.framework.FrameworkUtil;
31+
import org.osgi.test.junit5.context.BundleContextExtension;
32+
import org.osgi.test.junit5.service.ServiceExtension;
33+
34+
import java.time.Duration;
35+
36+
import static org.assertj.core.api.Assertions.assertThat;
37+
38+
@ExtendWith({ ServiceExtension.class, BundleContextExtension.class })
39+
class OsgiTest {
40+
41+
private final BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
42+
43+
private final MockClock clock = new MockClock();
44+
45+
@Test
46+
void testCoreResolves() {
47+
Bundle bundle = context.getBundle();
48+
assertThat(bundle).isNotNull();
49+
50+
CompositeMeterRegistry registry = Metrics.globalRegistry;
51+
assertThat(registry).isNotNull();
52+
}
53+
54+
@Test
55+
void testPrometheusMeterRegistryResolves() {
56+
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
57+
testMetrics(registry);
58+
assertThat(registry.scrape()).contains("micrometer_test_counter").contains(" micrometer_test_timer");
59+
}
60+
61+
@Test
62+
void testJmxMeterRegistryResolves() {
63+
JmxMeterRegistry registry = new JmxMeterRegistry(JmxConfig.DEFAULT, clock);
64+
testMetrics(registry);
65+
}
66+
67+
private void testMetrics(MeterRegistry registry) {
68+
registry.counter("micrometer.test.counter").increment();
69+
registry.timer("micrometer.test.timer").record(Duration.ofMillis(123));
70+
}
71+
72+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-tester: biz.aQute.tester.junit-platform
2+
-runfw: org.apache.felix.framework;
3+
-runee: ${project.osgiRunee}
4+
-runtrace: false
5+
6+
#uncomment to remote debug
7+
# -runjdb: 5005
8+
9+
-runrequires: \
10+
bnd.identity;id='org.apache.aries.spifly.dynamic.bundle',\
11+
bnd.identity;id='micrometer-osgi-test-slf4j2-tests',\
12+
bnd.identity;id='junit-jupiter-engine',\
13+
bnd.identity;id='junit-platform-launcher'
14+
15+
-runstartlevel: \
16+
order=sortbynameversion,\
17+
begin=-1
18+
19+
-runproperties: \
20+
org.osgi.framework.bsnversion=multiple

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ include 'micrometer-java21'
5151
include 'micrometer-jetty11'
5252
include 'micrometer-jetty12'
5353
include 'micrometer-osgi-test'
54+
include 'micrometer-osgi-test-slf4j2'
5455
include 'docs'

0 commit comments

Comments
 (0)