OSGi noClassDefFound для java.nio.files.FileSystems $ DefaultFileSystemHolder

1

в нашем приложении мы используем 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, как это, Феликс говорит мне следующее:

[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, которая ищет объект fileSystem для файла. Я что-то делаю неправильно, потому что мой код не находит DefaultFileSystemHolder? Это внутренний класс java, поэтому мне не нужно вводить импорт в мой MANIFEST.MF, верно?

Он работает на Ubuntu 14.04 с использованием Apache Felix 4.4.1 и Oracle Java 8 и работает с Maven.

заранее спасибо

  • 0
    Вы правы, что вам не нужно явно импортировать. Этот код работает на Java 7?
  • 0
    Еще не пробовал, потому что остальная часть кода использует Java8-вещи, такие как лямбда-выражения. Чтобы проверить это на Java 7 будет означать преобразовать остальные. Может быть, я могу создать небольшой тест в другой упаковке. Я дам вам результаты позже.
Показать ещё 4 комментария
Теги:
maven
osgi
filesystemwatcher

1 ответ

2
Лучший ответ

ТЛ; др

Добавьте в Felix следующую конфигурацию:

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

Объяснение:

Реализация FileSystems в Oracle JDK использует внутренний класс sun.nio.fs.DefaultFileSystemProvider. Это любопытство реализации JDK, поскольку он ожидает, что некоторые внутренние классы, такие как этот, будут видны из любого загрузчика классов. В OSGi единственными классами, которые всегда видны для всех пакетов, являются те, которые начинаются с java. , например, java.lang.String и т.д.

Конфигурация bootdelegation позволяет нам расширять набор всегда видимых пакетов. Он предназначен именно для этого сценария, то есть для внутренних классов JVM. Иногда это также полезно для запуска кода, который был инструментализован, например, для покрытия или профилирования. Это НЕ универсальный параметр для раскрытия дополнительного API от JDK.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню