imagej / imagej-updater

The automatic updater for ImageJ
Other
12 stars 15 forks source link

Deleting classpath entries during execution can crash the Updater #88

Open ctrueden opened 4 years ago

ctrueden commented 4 years ago

On macOS, populate a Fiji installation with pom-scijava 29.0.0-beta-3 artifacts like so:

git clone git://github.com/fiji/fiji --branch ff11b743691b886d66633af067c14af4783828d2 --depth 1
cd fiji
mvn scijava:populate-app -Dscijava.app.directory=/path/to/Fiji.app

Then try to update it:

/path/to/Fiji.app/Contents/MacOS/ImageJ-macosx --update update-force-pristine

After it updates all the JARs, it will emit this lovely error:

Error while executing the main() method of class 'net.imagej.updater.CommandLine':
java.util.ServiceConfigurationError: java.nio.charset.spi.CharsetProvider: Error reading configuration file
    at java.util.ServiceLoader.fail(ServiceLoader.java:232)
    at java.util.ServiceLoader.parse(ServiceLoader.java:309)
    at java.util.ServiceLoader.access$200(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.hasNextService(ServiceLoader.java:357)
    at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:393)
    at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:474)
    at java.nio.charset.Charset$1.getNext(Charset.java:350)
    at java.nio.charset.Charset$1.hasNext(Charset.java:365)
    at java.nio.charset.Charset$2.run(Charset.java:410)
    at java.nio.charset.Charset$2.run(Charset.java:407)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.nio.charset.Charset.lookupViaProviders(Charset.java:406)
    at java.nio.charset.Charset.lookup2(Charset.java:477)
    at java.nio.charset.Charset.lookup(Charset.java:464)
    at java.nio.charset.Charset.forName(Charset.java:528)
    at com.sun.org.apache.xml.internal.serializer.Encodings$EncodingInfos.findCharsetNameFor(Encodings.java:386)
    at com.sun.org.apache.xml.internal.serializer.Encodings$EncodingInfos.findCharsetNameFor(Encodings.java:422)
    at com.sun.org.apache.xml.internal.serializer.Encodings$EncodingInfos.loadEncodingInfo(Encodings.java:450)
    at com.sun.org.apache.xml.internal.serializer.Encodings$EncodingInfos.<init>(Encodings.java:308)
    at com.sun.org.apache.xml.internal.serializer.Encodings$EncodingInfos.<init>(Encodings.java:296)
    at com.sun.org.apache.xml.internal.serializer.Encodings.<clinit>(Encodings.java:564)
    at com.sun.org.apache.xml.internal.serializer.ToStream.<init>(ToStream.java:134)
    at com.sun.org.apache.xml.internal.serializer.ToXMLStream.<init>(ToXMLStream.java:67)
    at com.sun.org.apache.xml.internal.serializer.ToUnknownStream.<init>(ToUnknownStream.java:143)
    at com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory.getSerializationHandler(TransletOutputHandlerFactory.java:159)
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.getOutputHandler(TransformerImpl.java:445)
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerHandlerImpl.setResult(TransformerHandlerImpl.java:146)
    at net.imagej.updater.XMLFileWriter.createHandler(XMLFileWriter.java:287)
    at net.imagej.updater.XMLFileWriter.write(XMLFileWriter.java:151)
    at net.imagej.updater.FilesCollection.write(FilesCollection.java:439)
    at net.imagej.updater.CommandLine.update(CommandLine.java:573)
    at net.imagej.updater.CommandLine.main(CommandLine.java:1496)
    at net.imagej.updater.CommandLine.main(CommandLine.java:1415)
    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:498)
    at net.imagej.launcher.ClassLauncher.launch(ClassLauncher.java:291)
    at net.imagej.launcher.ClassLauncher.run(ClassLauncher.java:198)
    at net.imagej.launcher.ClassLauncher.main(ClassLauncher.java:89)
Caused by: java.io.FileNotFoundException: .../Fiji.app/jars/jcodings-1.0.27.jar (No such file or directory)
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:225)
    at java.util.zip.ZipFile.<init>(ZipFile.java:155)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.net.www.protocol.jar.URLJarFile.<init>(URLJarFile.java:93)
    at sun.net.www.protocol.jar.URLJarFile.getJarFile(URLJarFile.java:69)
    at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:84)
    at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:122)
    at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:152)
    at java.net.URL.openStream(URL.java:1045)
    at java.util.ServiceLoader.parse(ServiceLoader.java:304)
    ... 38 more

Because when invoking the XMLFileWriter, it leans on Xalan, which invokes the ServiceLoader mechanism looking for service plugins, which then tries to iterate the original classpath looking for META-INF/services/... entries, but some of the JARs have now been deleted. 😆

I don't see a robust way to fix this surgically.