Skip to content

Commit df49f59

Browse files
committed
When creating a modular JAR add the module descriptors directly to the archive
In order to update the module descriptors in a modular JAR file we're using the JDK `jar` tool but it requires files to be added to the JAR file in order the update to work. We know that a modular JAR file contains one or more `module-info.class` files (otherwise it is not a modular JAR) so we initially store them in temporary location and later use them to update the JAR file using the `jar` tool. It turns out adding just empty directory to the JAR file works as well. So lets add all `module-info.class` files directly to the JAR file and after that update it using an empty temporary directory. Closes #98 Fixes #97
1 parent c791213 commit df49f59

File tree

1 file changed

+18
-67
lines changed

1 file changed

+18
-67
lines changed

src/main/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiver.java

+18-67
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,12 @@
1818

1919
import org.apache.commons.compress.parallel.InputStreamSupplier;
2020
import org.codehaus.plexus.archiver.ArchiverException;
21-
import org.codehaus.plexus.archiver.util.ArchiveEntryUtils;
22-
import org.codehaus.plexus.archiver.util.ResourceUtils;
2321
import org.codehaus.plexus.archiver.zip.ConcurrentJarCreator;
24-
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
25-
import org.codehaus.plexus.util.FileUtils;
2622

2723
import java.io.File;
2824
import java.io.IOException;
2925
import java.io.PrintStream;
3026
import java.nio.file.Files;
31-
import java.nio.file.Path;
3227
import java.util.ArrayList;
3328
import java.util.List;
3429
import java.util.regex.Pattern;
@@ -63,8 +58,6 @@ public class JarToolModularJarArchiver
6358

6459
private boolean moduleDescriptorFound;
6560

66-
private Path tempDir;
67-
6861
public JarToolModularJarArchiver()
6962
{
7063
try
@@ -92,47 +85,15 @@ protected void zipFile( InputStreamSupplier is, ConcurrentJarCreator zOut,
9285
boolean addInParallel )
9386
throws IOException, ArchiverException
9487
{
95-
// We store the module descriptors in temporary location
96-
// and then add it to the JAR file using the JDK jar tool.
97-
// It may look strange at first, but to update a JAR file
98-
// you need to add new files[1] and the only files
99-
// we're sure that exists in modular JAR file
100-
// are the module descriptors.
101-
//
102-
// [1] There are some exceptions but we need at least one file to
103-
// ensure it will work in all cases.
10488
if ( jarTool != null && isModuleDescriptor( vPath ) )
10589
{
10690
getLogger().debug( "Module descriptor found: " + vPath );
10791

10892
moduleDescriptorFound = true;
109-
110-
// Copy the module descriptor to temporary directory
111-
// so later then can be added to the JAR archive
112-
// by the jar tool.
113-
114-
if ( tempDir == null )
115-
{
116-
tempDir = Files
117-
.createTempDirectory( "plexus-archiver-modular_jar-" );
118-
tempDir.toFile().deleteOnExit();
119-
}
120-
121-
File destFile = tempDir.resolve( vPath ).toFile();
122-
destFile.getParentFile().mkdirs();
123-
destFile.deleteOnExit();
124-
125-
ResourceUtils.copyFile( is.get(), destFile );
126-
ArchiveEntryUtils.chmod( destFile, mode );
127-
destFile.setLastModified( lastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
128-
? System.currentTimeMillis()
129-
: lastModified );
130-
}
131-
else
132-
{
133-
super.zipFile( is, zOut, vPath, lastModified,
134-
fromArchive, mode, symlinkDestination, addInParallel );
13593
}
94+
95+
super.zipFile( is, zOut, vPath, lastModified,
96+
fromArchive, mode, symlinkDestination, addInParallel );
13697
}
13798

13899
@Override
@@ -163,15 +124,11 @@ protected void postCreateArchive()
163124
"The JDK jar tool exited with " + result );
164125
}
165126
}
166-
catch ( ReflectiveOperationException | SecurityException e )
127+
catch ( IOException | ReflectiveOperationException | SecurityException e )
167128
{
168129
throw new ArchiverException( "Exception occurred " +
169130
"while creating modular JAR file", e );
170131
}
171-
finally
172-
{
173-
clearTempDirectory();
174-
}
175132
}
176133

177134
/**
@@ -203,7 +160,20 @@ private boolean isModuleDescriptor( String path )
203160
* main class, etc.
204161
*/
205162
private String[] getJarToolArguments()
163+
throws IOException
206164
{
165+
// We add empty temporary directory to the JAR file.
166+
// It may look strange at first, but to update a JAR file
167+
// you need to add new files[1]. If we add empty directory
168+
// it will be ignored (not added to the archive), but
169+
// the module descriptor will be updated and validated.
170+
//
171+
// [1] There are some exceptions (such as when the main class
172+
// is updated) but we need at least empty directory
173+
// to ensure it will work in all cases.
174+
File tempEmptyDir = Files.createTempDirectory( null ).toFile();
175+
tempEmptyDir.deleteOnExit();
176+
207177
List<String> args = new ArrayList<>();
208178

209179
args.add( "--update" );
@@ -228,29 +198,10 @@ private String[] getJarToolArguments()
228198
}
229199

230200
args.add( "-C" );
231-
args.add( tempDir.toFile().getAbsolutePath() );
201+
args.add( tempEmptyDir.getAbsolutePath() );
232202
args.add( "." );
233203

234204
return args.toArray( new String[]{} );
235205
}
236206

237-
/**
238-
* Makes best effort the clean up
239-
* the temporary directory used.
240-
*/
241-
private void clearTempDirectory()
242-
{
243-
try
244-
{
245-
if ( tempDir != null )
246-
{
247-
FileUtils.deleteDirectory( tempDir.toFile() );
248-
}
249-
}
250-
catch ( IOException e )
251-
{
252-
// Ignore. It is just best effort.
253-
}
254-
}
255-
256207
}

0 commit comments

Comments
 (0)