java - OSGi noClassDefFound for java.nio.files.FileSystems$DefaultFileSystemHolder

标签 java maven osgi filesystemwatcher

在我们的应用程序中,我们使用 ini 文件来配置 OSGi 应用程序。现在我考虑添加一个 WatchService 来检测更改并在必要时重新加载修改后的文件。

到目前为止我找到了多个教程。其中大多数都是相似的,结果如下: http://java.dzone.com/news/how-watch-file-system-changes 。我是这样采用的:

36: public Ini(final File file) throws IOException {
       if (!file.exists()) {
           throw new IOException("Ini-File does not exist.");
       } else if (!file.canRead()) {
40:         throw new IOException("Ini-File is not readable.");
       }
       iniFile = file;

        FileSystem fileSystem = FileSystems.getFileSystem(file.toURI());
45:     Path test = fileSystem.getPath(file.getAbsolutePath());
        Path ini = FileSystems.getDefault().getPath(file.getParent(), file.getName());
        Logger.debug(ini.toString());
        readIni(ini);

50:     service = FileSystems.getDefault().newWatchService();
        file.getParentFile().toPath().register(service, ENTRY_MODIFY);

        Thread watcher = new Thread(() -> {
            // noinspection InfiniteLoopStatement
55:             while (true) {
                WatchKey key = null;
                try {
                    key = service.take();
                    for (WatchEvent<?> event : key.pollEvents()) {
60:                     Logger.debug("event received");
                        if (event.kind() != ENTRY_MODIFY) {
                            continue;
                        }
                        WatchEvent<Path> ev = (WatchEvent<Path>) event;
65:
                        File filename = ev.context().toFile();
                        if (filename.getAbsolutePath().equals(iniFile.getAbsolutePath())) {
                            Logger.debug(filename.getName() + " has changed");

70:                         config = new HashMap<>();
                            try {
                                readIni(filename.toPath());
                            } catch(IOException e) {
                                Logger.warning(e);
75:                         }
                        }
                    }
                } catch (Exception e) {
                    Logger.warning(e);
80:             }
                if (key != null)
                    key.reset();
            }
        });
85: 
        watcher.start();
    }

创建新实例时,我首先检查文件是否存在。之后,我想创建一个 WatchService 来分析这个配置文件(一开始只有这个。稍后我将针对所有加载的文件更改为 1 个 WatchService)。

有几行(44 - 46)以不同的方式执行相同的操作。它们都不起作用。

现在,当我创建这样的 Ini 文件时,felix 会告诉我以下内容:

[ERROR]  : java.lang.NoClassDefFoundError: Could not initialize class java.nio.file.FileSystems$DefaultFileSystemHolder
java.lang.IllegalStateException: java.lang.NoClassDefFoundError: Could not initialize class java.nio.file.FileSystems$DefaultFileSystemHolder
    at org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler.__M_stateChanged(LifecycleCallbackHandler.java:171)
    at org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler.stateChanged(LifecycleCallbackHandler.java)
    at org.apache.felix.ipojo.InstanceManager.setState(InstanceManager.java:560)
    at org.apache.felix.ipojo.InstanceManager.start(InstanceManager.java:440)
    at org.apache.felix.ipojo.ComponentFactory.createInstance(ComponentFactory.java:179)
    at org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:319)
    at org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:240)
    at org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:312)
    at org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:306)
    at org.apache.felix.ipojo.extender.internal.queue.JobInfoCallable.call(JobInfoCallable.java:114)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class java.nio.file.FileSystems$DefaultFileSystemHolder
    at java.nio.file.FileSystems.getDefault(FileSystems.java:176)
    at java.nio.file.spi.FileSystemProvider.installedProviders(FileSystemProvider.java:156)
    at java.nio.file.FileSystems.getFileSystem(FileSystems.java:219)
    at df.core.config.internal.Ini.<init>(Ini.java:44)
    at df.core.config.internal.ConfigImpl.__M_addConfig(ConfigImpl.java:180)
    at df.core.config.internal.ConfigImpl.addConfig(ConfigImpl.java)
    at df.core.config.api.Config$$Proxy.addConfig(Unknown Source)
    at df.playground.IniTest.__M_validate(IniTest.java:24)
    at df.playground.IniTest.validate(IniTest.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.felix.ipojo.util.Callback.call(Callback.java:237)
    at org.apache.felix.ipojo.util.Callback.call(Callback.java:193)
    at org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallback.call(LifecycleCallback.java:86)
    at org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler.__M_stateChanged(LifecycleCallbackHandler.java:162)
    ... 13 more

这表明我在第 44 行搜索文件的文件系统对象。我是否做错了什么,因为我的代码找不到 DefaultFileSystemHolder?它是一个 java 内部类,所以我不需要在 MANIFEST.MF 中使用 import 语句,对吗?

它使用 Apache Felix 4.4.1 和 Oracle Java 8 在 Ubuntu 14.04 上运行,并使用 Maven 进行构建。

提前致谢

最佳答案

tl;博士

向 Felix 添加以下配置:

org.osgi.framework.bootdelegation=sun.nio.*

说明:

Oracle JDK 中的FileSystems 实现使用内部类sun.nio.fs.DefaultFileSystemProvider。这是 JDK 实现的一个好奇之处,因为它期望一些内部类(例如这个类)从任何类加载器中可见。在 OSGi 中,唯一对所有包始终可见的类是以 java. 开头,例如 java.lang.String 等。

bootdelegation 配置允许我们扩展始终可见的包集。它正是针对这种情况,即 JVM 内部类。有时,它对于运行已检测的代码也很有用,例如用于覆盖范围或分析。它不是用于从 JDK 公开其他 API 的通用设置。

关于java - OSGi noClassDefFound for java.nio.files.FileSystems$DefaultFileSystemHolder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25178582/

相关文章:

java - 为什么我的 hamcrest "contains"不能按预期工作?

java - 如何将我的 Spring Boot 发送给某人?

java - 快速简便地测试 OSGi 包的方法

tdd - 如何使用 Equinox/OSGi - Tycho - Eclipse RCP 环境遵循测试优先方法

java - xml 验证失败,出现需要属性和不允许属性的错误,该错误不明确

java - 哈希表反向查找以找到最小的键

Java8 与 Map 进行流传输?

java - 我成功地将maven包部署到jcenter,但是当我在其他项目上使用这个包时,它给了我一个错误

java - 是否能够在构建过程中将 REST 端点标记为忽略?

multithreading - 有关 OSGi 中的线程数的信息