-
-
Notifications
You must be signed in to change notification settings - Fork 351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Fix getOriginalSourceFragment and getRawJavadoc for zip file inputs #4850
fix: Fix getOriginalSourceFragment and getRawJavadoc for zip file inputs #4850
Conversation
Previously, zip files were flattened and stored as `<name><random number>.java`. This caused all methods that retrieve code at runtime, such as getOriginalSourceFragment or getRawJavadoc, to fail. This patch keeps the structure of the zip file intact while extracting it into a temporary folder. Consequently, the aforementioned methods are now able to find the source files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could add the reviews here as comments, but they are probably a bit too meta.
output.reset(); | ||
try (FileSystem zip = FileSystems.newFileSystem(URI.create("jar:" + file.toURI()), Map.of())) { | ||
Path tempFolder = Files.createTempDirectory("spoon-zip-file-proxy"); | ||
// Try to clean up - not guaranteed to work! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't guaranteed before as well and depends on the mood of the JVM. File#deleteOnExit()
which was used before in Sources also registers a shutdown hook.
zipInput.transferTo(output); | ||
files.add(new ZipFile(this, entry.getName(), output.toByteArray())); | ||
output.reset(); | ||
try (FileSystem zip = FileSystems.newFileSystem(URI.create("jar:" + file.toURI()), Map.of())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be made nicer in Java 13+, but for now we are stuck with it. URI.toString() should round-trip, so this should be safe for arbitrary paths.
} | ||
} catch (Exception e) { | ||
Launcher.LOGGER.error(e.getMessage(), e); | ||
Launcher.LOGGER.error("Error copying zip file contents", e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOGGER.error
crashes with null
messages, which is not ideal if you are trying to log such a message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks @I-Al-Istannen |
Description of the problem
Previously, zip files were flattened and stored as
<name><random number>.java
. This caused all methods that retrieve codeat runtime, such as
getOriginalSourceFragment
orgetRawJavadoc,
to fail.Chosen solution
This patch keeps the structure of the zip file intact while extracting it into a temporary folder. Consequently, the aforementioned methods are now able to find the source files.
There were multiple ways to proceed here. As JDT needs a copy anyways, I chose to proactively copy the files to disk instead of storing them in memory and copying them when the sources are prepared. Then I set
isActualFile
to true, tricking the relevant parts of spoon into treating the zip file as a regular file (which it mostly is by now, as it has an on-disk representation). The old constructor is kept in place (but will cause problems) as the class is public. Nobody should have used it in the first place, so maybe we could also delete it?Instead of changing the folder structure we could change the compilation unit name named passed to JDT, This sounds a bit deadly and is also absolutely not compatible with existing code looking at the compilation unit layer. Every compilation unit would be named
/tmp/MyClass381891.java
or similiar, which is not that helpful.Further possible features
Allow the user to specify where the temporary files should be stored when creating a
ZipFolder
. This can be easily retrofitted in the future though.