所以我用这个gradle结构构建了这个OSGi项目:
> Task :projects
------------------------------------------------------------
Root project 'project'
------------------------------------------------------------
Root project 'project'
No sub-projects
Included builds
+--- Included build ':callable-processor'
+--- Included build ':osgi-sun-misc'
+--- Included build ':path-collector'
+--- Included build ':robot-api'
+--- Included build ':robot-equinox'
+--- Included build ':robot-signal'
+--- Included build ':robot-instance'
+--- Included build ':utils'
--- Included build ':reactive'
主包是robot-equinox
。
在根(project
)上,我有以下build.gradle
配置:
// project
ext.baseVersion = '2.0.0'
ext.buildTag = "SNAPSHOT"
group 'project'
version "${baseVersion}-${buildTag}"
project {
quality = ALFA
}
configurations {
bundleInstall
bundleStart
misc
}
dependencies {
bundleInstall 'ch.qos.logback:logback-classic:1.3.5'
bundleInstall 'ch.qos.logback:logback-core:1.3.5'
bundleInstall 'org.slf4j:slf4j-api:2.0.5'
bundleInstall 'org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle:1.3.5'
bundleInstall 'prodist:callable-processor'
bundleInstall 'prodist:osgi-sun-misc'
bundleInstall 'prodist:path-collector'
bundleInstall 'prodist:reactive'
bundleInstall 'prodist:robot-api'
bundleStart 'ch.qos.logback:logback-classic:1.3.5'
bundleStart 'ch.qos.logback:logback-core:1.3.5'
bundleStart 'org.slf4j:slf4j-api:2.0.5'
bundleStart 'prodist:robot-equinox'
}
在robot-equinox
下,我有以下配置:
dependencies {
implementation group: 'prodist', name: 'callable-processor'
implementation group: 'prodist', name: 'path-collector'
implementation group: 'prodist', name: 'robot-api'
implementation group: 'prodist', name: 'reactive'
implementation group: 'prodist', name: 'robot-instance'
implementation group: 'prodist', name: 'utils'
compileOnly group: 'org.osgi', name: 'osgi.core', version: '6.0.0'
testImplementation group: 'org.hamcrest', name: 'hamcrest', version: '2.2'
testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.2.4'
testImplementation group: 'org.reactivestreams', name: 'reactive-streams-tck', version: '1.0.3'
testImplementation group: 'org.testng', name: 'testng', version: '7.1.0'
testCompileOnly group: 'org.osgi', name: 'osgi.core', version: '6.0.0'
}
我将给出main类的日志实现示例,它位于'project'下。
Application.java
package project.robot.equinox;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.*;
import java.security.SecureRandom;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public Application ()
{
MDC.put("product.name", ProductInfo.getName());
MDC.put("product.version", ProductInfo.getVersion());
}
public void activate (BundleContext bundleContext)
{
logger.atTrace().log(_S("activate: enter"));
}
...
}
但是当我启动应用程序时,我在osgi控制台得到这个消息:
osgi> SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
我的期望是,通过同时安装slf4j和logback, slf4j将识别logback实现并能够工作。我该如何解决这个问题?
好的,所以我找到了一个解决方案,我将把它发布在这里,这样它就可以帮助其他人面对同样的问题。
为了帮助SLF4J找到它的提供者,我创建了一个新的包osgi-log
——一个"日志包"。使用这个配置:
group 'project'
version '2.0.0'
dependencies {
api group: 'org.slf4j', name: 'slf4j-api', version: '2.0.5'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.3.5'
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.3.5'
implementation group: 'org.ow2.asm', name: 'asm', version: '5.2'
implementation group: 'org.ow2.asm', name: 'asm-commons', version: '5.2'
implementation group: 'org.ow2.asm', name: 'asm-util', version: '5.2'
implementation group: 'org.apache.aries.spifly', name: 'org.apache.aries.spifly.dynamic.bundle', version: '1.3.5'
}
然后,在每个使用log的包中,我添加了以下依赖项:
dependencies {
(...)
implementation group: 'project', name: 'osgi-log'
}
当我启动我的应用程序时,关于提供者的消息消失了,日志正在按预期注册。
我得出的结论是Apache Aries为SLF4J提供了一个ServiceLoader,并帮助他找到提供商,在我的情况下是logback。