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

非 Y 不嫁゛ 提交于 2019-12-08 04:26:32

问题


in our application, we're using ini files for the configuration of our OSGi apps. Now I thought about adding a WatchService to detect changes and reload the modified file if necessary.

I found multiple tutorials so far. Most of them are similar and result in something like the following: http://java.dzone.com/news/how-watch-file-system-changes. I adopted it like this:

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();
    }

When creating a new instance, I first check whether the file exist or not. After this, I want to create a WatchService profiling this config file (at first only this one. Later I will change to 1 WatchService for all loaded files).

There are several lines (44 - 46) doing the same in different ways. None of them worked.

Now when I create an Ini file like this, felix tells me the following:

[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

This states me to line 44 which searches for the fileSystem object for the file. Am I doing something wrong because my Code does not find the DefaultFileSystemHolder? It's a java internal class so I shouldn't need an import statement in my MANIFEST.MF, right?

It's running on Ubuntu 14.04 using Apache Felix 4.4.1 and Oracle Java 8 and build with Maven.

Thanks in advance


回答1:


tl;dr

Add the following configuration to Felix:

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

Explanation:

The FileSystems implementation in the Oracle JDK uses an internal class sun.nio.fs.DefaultFileSystemProvider. This is a curiosity of the JDK implementation, as it expects some internal classes such as this one to be visible from any classloader. In OSGi, the only classes that are always visible to all bundles are those beginning with java., such as java.lang.String etc.

The bootdelegation config allows us to extend the set of always-visible packages. It is intended for exactly this scenario, i.e. for JVM internal classes. Sometimes it is also useful for running code that has been instrumented, e.g. for coverage or profiling. It is NOT a general purpose setting for exposing additional API from the JDK.



来源:https://stackoverflow.com/questions/25178582/osgi-noclassdeffound-for-java-nio-files-filesystemsdefaultfilesystemholder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!