felix-atomos icon indicating copy to clipboard operation
felix-atomos copied to clipboard

NoSuchFileException with jlink VM using Atomos on executable jar

Open fipro78 opened this issue 3 years ago • 1 comments

Sorry if I again raise an issue that probably is only related to something wrong on my side.

I have created an executable jar using Bndtools and Atomos, similar to https://github.com/rotty3000/osgi-config-aff (jars attached). The .bndrun does not have the -runkeep instruction (see https://github.com/eclipse-equinox/equinox.bundles/issues/44).

atomos_executable_jars.zip

The executable jar with Atomos does actually not work: https://github.com/bndtools/bnd/issues/5243

But I can create a minimal JVM using jlink with this instruction:

For atomos_felix.jar:

${JAVA_HOME}/bin/jlink \
--no-header-files \
--no-man-pages \
--module-path atomos_felix.jar \
--add-modules felix.app \
--launcher start=felix.app \
--output jlink_output

For atomos_equinox.jar:

${JAVA_HOME}/bin/jlink \
--no-header-files \
--no-man-pages \
--module-path atomos_equinox.jar \
--add-modules equinox.app \
--launcher start=equinox.app \
--output jlink_output

I can start the VM over and over again without any issues. But of course the configuration is not stored as launch.keep=false.

If I modify the start script and set

JLINK_VM_OPTIONS=-Dlaunch.keep=true -Dlaunch.storage.dir=cache

the folder cache is created and there is a bundle cache and a persistent storage. So the configuration is persisted between launches. But on startup I get the following exception with the Felix variant:

ERROR: Error reloading cached bundle, removing it: .\cache\bundle51
java.nio.file.NoSuchFileException: .\cache\bundle51\version0.0\bundle.jar
        at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:53)
        at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:38)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.readAttributes(WindowsFileSystemProvider.java:199)
        at java.base/java.nio.file.Files.readAttributes(Files.java:1851)
        at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1264)
        at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:709)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:243)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:172)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:186)
        at org.apache.felix.framework.util.SecureAction.openZipFile(SecureAction.java:802)
        at org.apache.felix.framework.util.WeakZipFileFactory$WeakZipFile.<init>(WeakZipFileFactory.java:169)
        at org.apache.felix.framework.util.WeakZipFileFactory$WeakZipFile.<init>(WeakZipFileFactory.java:151)
        at org.apache.felix.framework.util.WeakZipFileFactory.create(WeakZipFileFactory.java:78)
        at org.apache.felix.framework.cache.JarRevision.<init>(JarRevision.java:83)
        at org.apache.felix.framework.cache.BundleArchive.createRevisionFromLocation(BundleArchive.java:819)
        at org.apache.felix.framework.cache.BundleArchive.reviseInternal(BundleArchive.java:491)
        at org.apache.felix.framework.cache.BundleArchive.<init>(BundleArchive.java:226)
        at org.apache.felix.framework.cache.BundleCache.getArchives(BundleCache.java:426)
        at org.apache.felix.framework.Felix.init(Felix.java:798)
        at org.apache.felix.framework.Felix.init(Felix.java:648)
        at aQute.launcher.Launcher.createFramework(Launcher.java:1249)
        at aQute.launcher.Launcher.activate(Launcher.java:494)
        at aQute.launcher.Launcher.launch(Launcher.java:403)
        at aQute.launcher.Launcher.run(Launcher.java:185)
        at aQute.launcher.Launcher.main(Launcher.java:161)
        at [email protected]/aQute.launcher.pre.EmbeddedLauncher.executeWithRunPath(EmbeddedLauncher.java:170)
        at [email protected]/aQute.launcher.pre.EmbeddedLauncher.findAndExecute(EmbeddedLauncher.java:119)
        at [email protected]/aQute.launcher.pre.EmbeddedLauncher.main(EmbeddedLauncher.java:52)

For Equinox I error logs in the cache folder that contain the following entries:

!MESSAGE Error validating installed bundle.
!STACK 0
java.lang.IllegalStateException: Connect Factory no longer has the module at locataion: atomos:boot:<USER_HOME>\AppData\Local\Temp\jar_cache13550892150743630974.tmp
	at org.eclipse.osgi.internal.connect.ConnectHookConfigurator$1$1.validate(ConnectHookConfigurator.java:84)
	at org.eclipse.osgi.storage.Storage.needsDiscarding(Storage.java:373)
	at org.eclipse.osgi.storage.Storage.refreshStaleBundles(Storage.java:352)
	at org.eclipse.osgi.storage.Storage.createStorage(Storage.java:187)
	at org.eclipse.osgi.internal.framework.EquinoxContainer.<init>(EquinoxContainer.java:108)
	at org.eclipse.osgi.launch.Equinox.<init>(Equinox.java:53)
	at org.eclipse.osgi.launch.EquinoxFactory.newFramework(EquinoxFactory.java:35)
	at aQute.launcher.Launcher.createConnect(Launcher.java:1280)
	at aQute.launcher.Launcher.createFramework(Launcher.java:1234)
	at aQute.launcher.Launcher.activate(Launcher.java:494)
	at aQute.launcher.Launcher.launch(Launcher.java:403)
	at aQute.launcher.Launcher.run(Launcher.java:185)
	at aQute.launcher.Launcher.main(Launcher.java:161)
	at [email protected]/aQute.launcher.pre.EmbeddedLauncher.executeWithRunPath(EmbeddedLauncher.java:170)
	at [email protected]/aQute.launcher.pre.EmbeddedLauncher.findAndExecute(EmbeddedLauncher.java:119)
	at [email protected]/aQute.launcher.pre.EmbeddedLauncher.main(EmbeddedLauncher.java:52)

As you might have noticed, I executed things on Windows, but I suspect it isn't an OS specific issue. I am also not sure if it is an Atomos issue or an issue of the bnd launcher.

BTW, I only see those exceptions in case of the jlink variant. Using a setup where all jars are located in a folder and Atomos is used to start, there are no exceptions.

fipro78 avatar May 12 '22 10:05 fipro78

I'm not sure this is an Atomos issue. It appears somewhere in the BND launcher it is creating some temporary JARs (e.g. jar_cache13550892150743630974.tmp) and then getting that content connected as Atomos content. I suspect the launcher is marking these temporary files as delete-on-exit. In the Equinox case we should be only logging the exception as a warning and continuing on as if the bundle is not installed at all. I'm not sure what the Felix framework does in this case.

tjwatson avatar May 16 '22 13:05 tjwatson