From eba4dd1d8ad4af85b0d0f156df6c236c490ff3e5 Mon Sep 17 00:00:00 2001 From: BJ Hargrave Date: Sat, 14 May 2022 09:17:36 -0400 Subject: [PATCH 1/4] ci: Update github actions Signed-off-by: BJ Hargrave --- .github/scripts/{build.sh => ci-build.sh} | 0 .github/scripts/{publish.sh => ci-publish.sh} | 0 .github/workflows/cibuild.yml | 23 ++++++++++++------- .github/workflows/codeql-analysis.yml | 6 +++-- 4 files changed, 19 insertions(+), 10 deletions(-) rename .github/scripts/{build.sh => ci-build.sh} (100%) rename .github/scripts/{publish.sh => ci-publish.sh} (100%) diff --git a/.github/scripts/build.sh b/.github/scripts/ci-build.sh similarity index 100% rename from .github/scripts/build.sh rename to .github/scripts/ci-build.sh diff --git a/.github/scripts/publish.sh b/.github/scripts/ci-publish.sh similarity index 100% rename from .github/scripts/publish.sh rename to .github/scripts/ci-publish.sh diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index fa6db5f..12c14b4 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -22,13 +22,17 @@ on: push: branches-ignore: - 'dependabot/**' - paths-ignore: - - '.github/**/*codeql*' - - '.github/*.yml' + paths: + - '**' + - '!docs/**' + - '!.github/**' + - '.github/**/*ci*' pull_request: - paths-ignore: - - '.github/**/*codeql*' - - '.github/*.yml' + paths: + - '**' + - '!docs/**' + - '!.github/**' + - '.github/**/*ci*' env: LC_ALL: en_US.UTF-8 @@ -41,6 +45,9 @@ defaults: run: shell: bash +permissions: + contents: read + jobs: build: strategy: @@ -67,7 +74,7 @@ jobs: - name: Build id: build run: | - ./.github/scripts/build.sh + ./.github/scripts/ci-build.sh - name: Configure settings.xml for Publish if: ${{ matrix.canonical }} uses: actions/setup-java@v3 @@ -82,7 +89,7 @@ jobs: - name: Publish if: ${{ matrix.canonical }} run: | - ./.github/scripts/publish.sh -Possrh + ./.github/scripts/ci-publish.sh -Possrh env: GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index cef1012..8bb60b3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -41,11 +41,13 @@ defaults: run: shell: bash +permissions: + contents: read + jobs: analyze: permissions: - # required for all workflows - security-events: write + security-events: write # for github/codeql-action/analyze to upload SARIF results strategy: fail-fast: false matrix: From b33ccec8ad190f3c99c839544e89466e093ec45e Mon Sep 17 00:00:00 2001 From: BJ Hargrave Date: Sat, 14 May 2022 09:17:53 -0400 Subject: [PATCH 2/4] build: Update maven version Signed-off-by: BJ Hargrave --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index b7cb93e..22f219d 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar From fce7e271c816185c9098a29412dd3c995d7029a5 Mon Sep 17 00:00:00 2001 From: BJ Hargrave Date: Sat, 14 May 2022 09:56:32 -0400 Subject: [PATCH 3/4] stub: Use Proxy and reflection for stub logging This avoids a direct implementation of the org.osgi.service.log.Logger type which causes Bnd to use a narrow provider import package version range on the org.osgi.service.log package import. Fixes https://github.com/osgi/slf4j-osgi/issues/70 Signed-off-by: BJ Hargrave --- src/main/java/org/slf4j/impl/SLF4JLogger.java | 187 ++++-------------- .../org/slf4j/impl/SLF4JLoggerFactory.java | 6 +- 2 files changed, 46 insertions(+), 147 deletions(-) diff --git a/src/main/java/org/slf4j/impl/SLF4JLogger.java b/src/main/java/org/slf4j/impl/SLF4JLogger.java index 77446b7..f449891 100644 --- a/src/main/java/org/slf4j/impl/SLF4JLogger.java +++ b/src/main/java/org/slf4j/impl/SLF4JLogger.java @@ -26,23 +26,27 @@ import org.slf4j.helpers.MarkerIgnoringBase; import org.slf4j.helpers.MessageFormatter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + /** * slf4j-osgi implementation of org.slf4j.Logger. - * + * * @author $Id$ */ class SLF4JLogger extends MarkerIgnoringBase { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; @SuppressWarnings("unused") private static final Class stubClass = StubLogger.class; final transient Bundle bundle; final transient LoggerFactoryTracker tracker; private transient volatile Logger stub; - SLF4JLogger(Bundle bundle, String name) { + SLF4JLogger(Bundle bundle, String name, LoggerFactoryTracker tracker) { this.name = name; this.bundle = bundle; - tracker = SLF4JLoggerFactory.getTracker(); + this.tracker = tracker; } private Logger getLogger() { @@ -50,7 +54,7 @@ private Logger getLogger() { if (logger == null) { logger = stub; if (logger == null) { - stub = logger = new StubLogger(); + stub = logger = newStubLogger(); } } return logger; @@ -281,194 +285,125 @@ public void error(String format, Object... argArray) { } } + /** + * Make a new StubLogger for when no LoggerFactory is available. + *

+ * Uses Proxy and reflection to avoid directly implementing org.osgi.service.log.Logger + * and thus using a narrow provider import version range for the org.osgi.service.log package. + */ + Logger newStubLogger() { + final StubLogger delegate = new StubLogger(); + final Class delegateClass = delegate.getClass(); + return (Logger) Proxy.newProxyInstance(delegateClass.getClassLoader(), new Class[] { Logger.class }, (proxy, method, args) -> { + Method delegateMethod; + try { + delegateMethod = delegateClass.getMethod(method.getName(), method.getParameterTypes()); + } catch (NoSuchMethodException e) { + throw new UnsupportedOperationException(e); + } + try { + return delegateMethod.invoke(delegate, args); + } catch (InvocationTargetException e) { + Throwable t = e; + for (Throwable cause; (t instanceof InvocationTargetException) && ((cause = t.getCause()) != null); ) { + t = cause; + } + throw t; + } + }); + } + /** * Used when no LoggerFactory is available. */ - class StubLogger implements Logger { + @SuppressWarnings("unused") + class StubLogger { private static final boolean TRACE_ENABLED = false; private static final boolean DEBUG_ENABLED = false; private static final boolean INFO_ENABLED = false; private static final boolean WARN_ENABLED = true; private static final boolean ERROR_ENABLED = true; - @Override + StubLogger() {} + public String getName() { return SLF4JLogger.this.getName(); } - @Override public boolean isTraceEnabled() { return TRACE_ENABLED; } - @Override public void trace(String msg) { if (TRACE_ENABLED) { tracker.log(bundle, getName(), LogLevel.TRACE, msg, null); } } - @Override public void trace(String msg, Object t) { if (TRACE_ENABLED) { tracker.log(bundle, getName(), LogLevel.TRACE, msg, (Throwable) t); } } - @Override - public void trace(String format, Object arg1, Object arg2) { - if (TRACE_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void trace(String format, Object... arguments) { - if (TRACE_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void trace(LoggerConsumer consumer) throws E { - if (TRACE_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override public boolean isDebugEnabled() { return DEBUG_ENABLED; } - @Override public void debug(String msg) { if (DEBUG_ENABLED) { tracker.log(bundle, getName(), LogLevel.DEBUG, msg, null); } } - @Override public void debug(String msg, Object t) { if (DEBUG_ENABLED) { tracker.log(bundle, getName(), LogLevel.DEBUG, msg, (Throwable) t); } } - @Override - public void debug(String format, Object arg1, Object arg2) { - if (DEBUG_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void debug(String format, Object... arguments) { - if (DEBUG_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void debug(LoggerConsumer consumer) throws E { - if (DEBUG_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override public boolean isInfoEnabled() { return INFO_ENABLED; } - @Override public void info(String msg) { if (INFO_ENABLED) { tracker.log(bundle, getName(), LogLevel.INFO, msg, null); } } - @Override public void info(String msg, Object t) { if (INFO_ENABLED) { tracker.log(bundle, getName(), LogLevel.INFO, msg, (Throwable) t); } } - @Override - public void info(String format, Object arg1, Object arg2) { - if (INFO_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void info(String format, Object... arguments) { - if (INFO_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void info(LoggerConsumer consumer) throws E { - if (INFO_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override public boolean isWarnEnabled() { return WARN_ENABLED; } - @Override public void warn(String msg) { if (WARN_ENABLED) { tracker.log(bundle, getName(), LogLevel.WARN, msg, null); } } - @Override public void warn(String msg, Object t) { if (WARN_ENABLED) { tracker.log(bundle, getName(), LogLevel.WARN, msg, (Throwable) t); } } - @Override - public void warn(String format, Object arg1, Object arg2) { - if (WARN_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void warn(String format, Object... arguments) { - if (WARN_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void warn(LoggerConsumer consumer) throws E { - if (WARN_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override public boolean isErrorEnabled() { return ERROR_ENABLED; } - @Override public void error(String msg) { if (ERROR_ENABLED) { tracker.log(bundle, getName(), LogLevel.ERROR, msg, null); } } - @Override public void error(String msg, Object t) { if (ERROR_ENABLED) { tracker.log(bundle, getName(), LogLevel.ERROR, msg, (Throwable) t); @@ -476,44 +411,8 @@ public void error(String msg, Object t) { } @Override - public void error(String format, Object arg1, Object arg2) { - if (ERROR_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void error(String format, Object... arguments) { - if (ERROR_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void error(LoggerConsumer consumer) throws E { - if (ERROR_ENABLED) { - throw new UnsupportedOperationException(); - } - } - - @Override - public void audit(String message) { - throw new UnsupportedOperationException(); - } - - @Override - public void audit(String format, Object arg) { - throw new UnsupportedOperationException(); - } - - @Override - public void audit(String format, Object arg1, Object arg2) { - throw new UnsupportedOperationException(); - } - - @Override - public void audit(String format, Object... arguments) { - throw new UnsupportedOperationException(); + public String toString() { + return getClass().getName() + "(" + getName() + ")"; } } } diff --git a/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java b/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java index 7a03fa2..341024c 100644 --- a/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java +++ b/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java @@ -36,7 +36,7 @@ /** * slf4j-osgi implementation of org.slf4j.ILoggerFactory. - * + * * @author $Id$ */ class SLF4JLoggerFactory implements org.slf4j.ILoggerFactory { @@ -162,7 +162,7 @@ static LoggerFactoryTracker getTracker() { /** * Return a named Logger. - * + * * @return A Logger for the specified name. */ @Override @@ -171,7 +171,7 @@ public org.slf4j.Logger getLogger(String name) { if (logger != null) { return logger; } - logger = loggers.computeIfAbsent(name, n -> new SLF4JLogger(bundle, n)); + logger = loggers.computeIfAbsent(name, n -> new SLF4JLogger(bundle, n, getTracker())); return logger; } } From 3c28e18b948d8e96a16d8264790706f7b0fb0b1f Mon Sep 17 00:00:00 2001 From: BJ Hargrave Date: Sat, 14 May 2022 18:26:59 -0400 Subject: [PATCH 4/4] build: Update to add OSGi testing We add a simple log test to confirm the binding properly works and sends a log to the OSGi Log Service. Signed-off-by: BJ Hargrave --- pom.xml | 314 ++++++++++++++++-- .../org/slf4j/impl/LoggerFactoryTracker.java | 32 +- src/main/java/org/slf4j/impl/SLF4JLogger.java | 12 +- .../org/slf4j/impl/SLF4JLoggerFactory.java | 39 ++- .../org/slf4j/impl/StaticLoggerBinder.java | 10 +- src/test/java/.gitignore | 0 .../java/org/osgi/test/slf4j/LogTest.java | 77 +++++ test.bndrun | 58 ++++ 8 files changed, 469 insertions(+), 73 deletions(-) delete mode 100644 src/test/java/.gitignore create mode 100644 src/test/java/org/osgi/test/slf4j/LogTest.java create mode 100644 test.bndrun diff --git a/pom.xml b/pom.xml index bb1bc15..7b2e32f 100644 --- a/pom.xml +++ b/pom.xml @@ -18,25 +18,39 @@ --> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.osgi slf4j.osgi + ${revision} SLF4J over OSGi Log Service Binding slf4j.osgi - 1.7.1-SNAPSHOT + jar + + 1.7.1-SNAPSHOT 1980-02-01T00:00:00Z UTF-8 + + ${maven.test.skip} 1.8 8 ${java.version} ${java.version} 6.2.0 1.7.36 + 8.1.0 + 1.0.0 + 1.0.0 + 1.8.0 + 1.5.4 + 1.4.0 + 5.8.2 + 3.22.0 + 1.1.0 https://www.osgi.org @@ -56,7 +70,7 @@ https://github.com/osgi/slf4j-osgi scm:git:https://github.com/osgi/slf4j-osgi.git scm:git:git@github.com:osgi/slf4j-osgi.git - HEAD + ${revision} @@ -84,34 +98,157 @@ + + + + org.osgi + osgi.annotation + ${osgi.annotation.version} + provided + + + org.osgi + org.osgi.service.log + ${osgi.log.version} + + + org.osgi + org.osgi.dto + ${osgi.dto.version} + provided + + + org.osgi + org.osgi.resource + ${osgi.resource.version} + provided + + + org.osgi + org.osgi.framework + ${osgi.framework.version} + provided + + + org.osgi + org.osgi.util.tracker + ${osgi.tracker.version} + provided + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-nop + ${slf4j.version} + provided + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.junit + junit-bom + ${junit-jupiter.version} + pom + import + + + org.osgi + org.osgi.test.common + ${osgi-test.version} + test + + + org.osgi + org.osgi.test.junit5 + ${osgi-test.version} + test + + + org.osgi + org.osgi.test.assertj.framework + ${osgi-test.version} + test + + + org.osgi + org.osgi.test.assertj.log + ${osgi-test.version} + test + + + org.eclipse.platform + org.eclipse.osgi + 3.17.200 + test + + + + org.osgi osgi.annotation - 8.1.0 - provided org.osgi - osgi.core - 6.0.0 - provided + org.osgi.dto + + + org.osgi + org.osgi.resource + + + org.osgi + org.osgi.framework + + + org.osgi + org.osgi.util.tracker org.osgi org.osgi.service.log - 1.4.0 org.slf4j slf4j-api - ${slf4j.version} org.slf4j slf4j-nop - ${slf4j.version} - provided + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + + + org.osgi + org.osgi.test.common + + + org.osgi + org.osgi.test.assertj.framework + + + org.osgi + org.osgi.test.junit5 + + + org.osgi + org.osgi.test.assertj.log @@ -123,8 +260,14 @@ bnd-maven-plugin ${bnd.version} true - - + + default-jar + + jar + + + - - + + + - jar + test-jar - jar + test-jar + + false + + junit5 + @@ -164,6 +316,61 @@ + + biz.aQute.bnd + bnd-resolver-maven-plugin + ${bnd.version} + + + + resolve-test + pre-integration-test + + resolve + + + + test.bndrun + + false + true + false + + compile + runtime + test + + + + + + + biz.aQute.bnd + bnd-testing-maven-plugin + ${bnd.version} + + + + testing + + testing + + + + test.bndrun + + false + true + false + + compile + runtime + test + + + + + org.apache.maven.plugins maven-compiler-plugin @@ -185,6 +392,10 @@ org.apache.maven.plugins maven-surefire-plugin 2.22.2 + + + true + org.apache.maven.plugins @@ -221,6 +432,7 @@ false none + true @@ -247,9 +459,6 @@ org.codehaus.mojo flatten-maven-plugin 1.2.7 - - oss - flatten @@ -257,6 +466,9 @@ flatten + + oss + flatten-clean @@ -279,16 +491,12 @@ bnd-baseline-maven-plugin - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-resources-plugin + biz.aQute.bnd + bnd-resolver-maven-plugin - org.apache.maven.plugins - maven-install-plugin + biz.aQute.bnd + bnd-testing-maven-plugin org.apache.maven.plugins @@ -315,11 +523,55 @@ ${java.release} + + bnd-next + + 6.4.0-SNAPSHOT + + + + bnd-releases + https://bndtools.jfrog.io/bndtools/libs-release/ + default + + false + + + + bnd-snapshots + https://bndtools.jfrog.io/bndtools/libs-snapshot/ + default + + false + + + + + + bnd-releases + https://bndtools.jfrog.io/bndtools/libs-release/ + default + + false + + + + bnd-snapshots + https://bndtools.jfrog.io/bndtools/libs-snapshot/ + default + + false + + + + ossrh true - true + true + true + true diff --git a/src/main/java/org/slf4j/impl/LoggerFactoryTracker.java b/src/main/java/org/slf4j/impl/LoggerFactoryTracker.java index e4fe114..96dd8b0 100644 --- a/src/main/java/org/slf4j/impl/LoggerFactoryTracker.java +++ b/src/main/java/org/slf4j/impl/LoggerFactoryTracker.java @@ -35,16 +35,16 @@ /** * slf4j-osgi implementation OSGi Logger handler. - * + * * @author $Id$ */ -class LoggerFactoryTracker extends ServiceTracker { +class LoggerFactoryTracker extends ServiceTracker { static class Entry { - private final Bundle bundle; - private final String name; - private final LogLevel level; - private final String message; - private final Throwable t; + private final Bundle bundle; + private final String name; + private final LogLevel level; + private final String message; + private final Throwable t; Entry(Bundle bundle, String name, LogLevel level, String message, Throwable t) { this.bundle = bundle; @@ -71,31 +71,31 @@ public String toString() { void log(LoggerFactory factory) { Logger logger = factory.getLogger(bundle, name, Logger.class); switch (level) { - case TRACE : + case TRACE: logger.trace(message, t); break; - case DEBUG : + case DEBUG: logger.debug(message, t); break; - case INFO : + case INFO: logger.info(message, t); break; - case WARN : + case WARN: logger.warn(message, t); break; - case ERROR : + case ERROR: logger.error(message, t); break; - default : + default: logger.audit(message, t); break; } } } - private static final int QUEUE_SIZE = 200; - private final BlockingQueue queue; - private volatile LoggerFactory firstFactory = null; + private static final int QUEUE_SIZE = 200; + private final BlockingQueue queue; + private volatile LoggerFactory firstFactory = null; LoggerFactoryTracker(BundleContext context) { super(context, LoggerFactory.class.getName(), null); diff --git a/src/main/java/org/slf4j/impl/SLF4JLogger.java b/src/main/java/org/slf4j/impl/SLF4JLogger.java index f449891..31a1361 100644 --- a/src/main/java/org/slf4j/impl/SLF4JLogger.java +++ b/src/main/java/org/slf4j/impl/SLF4JLogger.java @@ -294,7 +294,7 @@ public void error(String format, Object... argArray) { Logger newStubLogger() { final StubLogger delegate = new StubLogger(); final Class delegateClass = delegate.getClass(); - return (Logger) Proxy.newProxyInstance(delegateClass.getClassLoader(), new Class[] { Logger.class }, (proxy, method, args) -> { + return (Logger) Proxy.newProxyInstance(delegateClass.getClassLoader(), new Class[] {Logger.class}, (proxy, method, args) -> { Method delegateMethod; try { delegateMethod = delegateClass.getMethod(method.getName(), method.getParameterTypes()); @@ -318,11 +318,11 @@ Logger newStubLogger() { */ @SuppressWarnings("unused") class StubLogger { - private static final boolean TRACE_ENABLED = false; - private static final boolean DEBUG_ENABLED = false; - private static final boolean INFO_ENABLED = false; - private static final boolean WARN_ENABLED = true; - private static final boolean ERROR_ENABLED = true; + private static final boolean TRACE_ENABLED = false; + private static final boolean DEBUG_ENABLED = false; + private static final boolean INFO_ENABLED = false; + private static final boolean WARN_ENABLED = true; + private static final boolean ERROR_ENABLED = true; StubLogger() {} diff --git a/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java b/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java index 341024c..f1eb88e 100644 --- a/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java +++ b/src/main/java/org/slf4j/impl/SLF4JLoggerFactory.java @@ -46,6 +46,7 @@ static class Central extends SecurityManager implements SynchronousBundleListene static final LoggerFactoryTracker tracker; private static final Central central; private static final ConcurrentMap factories; + static { self = FrameworkUtil.getBundle(SLF4JLoggerFactory.class); assert self != null; @@ -67,26 +68,32 @@ public Central run() { private static BundleContext getSystemBundleContext(Bundle bundle) { BundleContext bc = bundle.getBundleContext(); if (bc != null) { - return bc.getBundle(Constants.SYSTEM_BUNDLE_ID).getBundleContext(); + return bc.getBundle(Constants.SYSTEM_BUNDLE_ID) + .getBundleContext(); } BundleWiring wiring = bundle.adapt(BundleWiring.class); List wires = wiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE); for (BundleWire wire : wires) { - if ("org.osgi.framework" - .equals(wire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) { - return wire.getProviderWiring().getBundle().getBundleContext(); + if ("org.osgi.framework".equals(wire.getCapability() + .getAttributes() + .get(PackageNamespace.PACKAGE_NAMESPACE))) { + return wire.getProviderWiring() + .getBundle() + .getBundleContext(); } } return null; } private static Bundle getCallerBundle() { - StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + StackTraceElement[] stack = Thread.currentThread() + .getStackTrace(); boolean foundGetLogger = false; for (int i = 5; i < stack.length; i++) { StackTraceElement trace = stack[i]; - if (trace.getClassName().equals("org.slf4j.LoggerFactory") - && trace.getMethodName().equals("getLogger")) { + if (trace.getClassName() + .equals("org.slf4j.LoggerFactory") && trace.getMethodName() + .equals("getLogger")) { foundGetLogger = true; continue; } @@ -131,15 +138,15 @@ public Void run() { @Override public void bundleChanged(BundleEvent event) { switch (event.getType()) { - case BundleEvent.UNRESOLVED: - Bundle b = event.getBundle(); - if (b.equals(self)) { - factories.clear(); - AccessController.doPrivileged(selfRemove); - } else { - factories.remove(b); - } - break; + case BundleEvent.UNRESOLVED: + Bundle b = event.getBundle(); + if (b.equals(self)) { + factories.clear(); + AccessController.doPrivileged(selfRemove); + } else { + factories.remove(b); + } + break; } } } diff --git a/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/src/main/java/org/slf4j/impl/StaticLoggerBinder.java index a1dc8e6..bf17630 100644 --- a/src/main/java/org/slf4j/impl/StaticLoggerBinder.java +++ b/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -23,17 +23,18 @@ /** * slf4j-osgi implementation of org.slf4j.impl.StaticLoggerBinder. - * + * * @author $Id$ */ public class StaticLoggerBinder implements LoggerFactoryBinder { - private static final StaticLoggerBinder SINGLETON; + private static final StaticLoggerBinder SINGLETON; /** * Declare the version of the SLF4J API this implementation is compiled * against. The value of this field is modified with each major release. */ - public static final String REQUESTED_API_VERSION; + public static final String REQUESTED_API_VERSION; + static { SINGLETON = new StaticLoggerBinder(); REQUESTED_API_VERSION = "1.7.0"; @@ -52,6 +53,7 @@ public ILoggerFactory getLoggerFactory() { @Override public String getLoggerFactoryClassStr() { - return getLoggerFactory().getClass().getName(); + return getLoggerFactory().getClass() + .getName(); } } diff --git a/src/test/java/.gitignore b/src/test/java/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/org/osgi/test/slf4j/LogTest.java b/src/test/java/org/osgi/test/slf4j/LogTest.java new file mode 100644 index 0000000..4b04009 --- /dev/null +++ b/src/test/java/org/osgi/test/slf4j/LogTest.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) Contributors to the Eclipse Foundation + * + * Licensed 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. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package org.osgi.test.slf4j; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.osgi.framework.BundleContext; +import org.osgi.service.log.LogEntry; +import org.osgi.service.log.LogLevel; +import org.osgi.service.log.LogReaderService; +import org.osgi.test.assertj.log.logentry.LogEntryAssert; +import org.osgi.test.common.annotation.InjectBundleContext; +import org.osgi.test.common.annotation.InjectService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Objects; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LogTest { + private String testName; + private Logger logger; + + @BeforeEach + void setUp(TestInfo info) { + testName = info.getTestClass() + .map(Class::getName) + .get() + "." + info.getTestMethod() + .map(Method::getName) + .get(); + logger = LoggerFactory.getLogger(testName); + assertThat(logger).isNotNull(); + } + + @Test + void log_test(@InjectService LogReaderService lr, @InjectBundleContext BundleContext bc) { + Exception exception = new Exception(); + logger.warn("Test {} from {}", "message", testName, exception); + Optional first = Collections.list(lr.getLog()) + .stream() + .filter(logEntry -> Objects.equals(logEntry.getLoggerName(), testName)) + .findFirst(); + assertThat(first).isNotEmpty(); + LogEntryAssert logEntryAssert = LogEntryAssert.assertThat(first.get()) + .hasLogLevel(LogLevel.WARN) + .hasLoggerName(testName) + .hasBundle(bc.getBundle()) + .hasServiceReference(null); + logEntryAssert.hasExceptionThat() + .isNotNull(); + logEntryAssert.hasMessageThat() + .startsWith("Test") + .contains("message") + .contains(testName); + } +} diff --git a/test.bndrun b/test.bndrun new file mode 100644 index 0000000..371bac5 --- /dev/null +++ b/test.bndrun @@ -0,0 +1,58 @@ +# Copyright (c) Contributors to the Eclipse Foundation +# +# Licensed 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. +# +# SPDX-License-Identifier: Apache-2.0 + +-tester: biz.aQute.tester.junit-platform + +-runvm: ${def;argLine} + +-runfw: org.eclipse.osgi +-resolve.effective: active +-runproperties: \ + org.osgi.framework.bootdelegation='sun.misc,sun.reflect',\ + osgi.console=,\ + equinox.log.history.max=10 + +# For debug output +#-runtrace: true +# For remote debugging +#-runjdb: 8080 + +-runrequires: \ + bnd.identity;id='${project.artifactId}',\ + bnd.identity;id='${project.artifactId}-tests',\ + bnd.identity;id='junit-jupiter-engine',\ + bnd.identity;id='junit-platform-launcher' +# This will help us keep -runbundles sorted +-runstartlevel: \ + order=sortbynameversion,\ + begin=-1 +# The following is calculated by the bnd-resolver-maven-plugin +-runbundles: \ + assertj-core;version='[3.22.0,3.22.1)',\ + junit-jupiter-api;version='[5.8.2,5.8.3)',\ + junit-jupiter-engine;version='[5.8.2,5.8.3)',\ + junit-jupiter-params;version='[5.8.2,5.8.3)',\ + junit-platform-commons;version='[1.8.2,1.8.3)',\ + junit-platform-engine;version='[1.8.2,1.8.3)',\ + junit-platform-launcher;version='[1.8.2,1.8.3)',\ + org.opentest4j;version='[1.2.0,1.2.1)',\ + org.osgi.test.assertj.framework;version='[1.1.0,1.1.1)',\ + org.osgi.test.assertj.log;version='[1.1.0,1.1.1)',\ + org.osgi.test.common;version='[1.1.0,1.1.1)',\ + org.osgi.test.junit5;version='[1.1.0,1.1.1)',\ + slf4j.api;version='[1.7.36,1.7.37)',\ + slf4j.osgi;version='[1.7.1,1.7.2)',\ + slf4j.osgi-tests;version='[1.7.1,1.7.2)'