Speeding up jmod
Andrej Golovnin
andrej.golovnin at gmail.com
Sun May 1 13:50:13 UTC 2016
Hi Alan,
If you would like to improve the performance a little bit more,
you can make additional changes (see the patch) to JmodTask
and maybe Claes can rerun his tests to see if it helps.
The patch makes following changes:
- reads module info in a little bit more efficient way.
- avoids duplicate searching for module info
when hashing of modules is required.
- uses String#lastIndexOf(int) in toPackageName(ZipEntry)
instead of String#lastIndexOf(String).
- avoids checking for every directory entry in a JarFile if it ends
with “module-info.class”.
Best regards,
Andrej Golovnin
-------------- next part --------------
diff -r 7210b5dbd92f src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java
--- a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Sat Apr 30 16:41:08 2016 -0700
+++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Sun May 01 15:43:24 2016 +0200
@@ -373,7 +373,6 @@
final String osArch = options.osArch;
final String osVersion = options.osVersion;
final List<PathMatcher> excludes = options.excludes;
- final Hasher hasher = hasher();
JmodFileWriter() { }
@@ -400,31 +399,34 @@
* on the class path of directories and JAR files.
*/
Supplier<InputStream> newModuleInfoSupplier() throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] bytes = null;
for (Path e: classpath) {
if (Files.isDirectory(e)) {
Path mi = e.resolve(MODULE_INFO);
if (Files.isRegularFile(mi)) {
- Files.copy(mi, baos);
+ bytes = Files.readAllBytes(mi);
break;
}
} else if (Files.isRegularFile(e) && e.toString().endsWith(".jar")) {
try (JarFile jf = new JarFile(e.toFile())) {
ZipEntry entry = jf.getEntry(MODULE_INFO);
if (entry != null) {
- jf.getInputStream(entry).transferTo(baos);
- break;
+ byte[] tmp = new byte[(int) entry.getSize()];
+ if (jf.getInputStream(entry).read(tmp) == tmp.length) {
+ bytes = tmp;
+ break;
+ }
}
} catch (ZipException x) {
// Skip. Do nothing. No packages will be added.
}
}
}
- if (baos.size() == 0) {
+ if (bytes == null) {
return null;
} else {
- byte[] bytes = baos.toByteArray();
- return () -> new ByteArrayInputStream(bytes);
+ byte[] tmp = bytes;
+ return () -> new ByteArrayInputStream(tmp);
}
}
@@ -450,7 +452,6 @@
try (InputStream in = miSupplier.get()) {
descriptor = ModuleDescriptor.read(in);
}
-
// copy the module-info.class into the jmod with the additional
// attributes for the version, main class and other meta data
try (InputStream in = miSupplier.get()) {
@@ -479,6 +480,7 @@
if (moduleVersion != null)
extender.version(moduleVersion);
+ Hasher hasher = hasher(descriptor);
if (hasher != null) {
ModuleHashes moduleHashes = hasher.computeHashes(descriptor.name());
if (moduleHashes != null) {
@@ -504,50 +506,36 @@
* The jmod file is being created and does not exist in the
* given modulepath.
*/
- private Hasher hasher() {
+ private Hasher hasher(ModuleDescriptor descriptor) {
if (options.modulesToHash == null)
return null;
- try {
- Supplier<InputStream> miSupplier = newModuleInfoSupplier();
- if (miSupplier == null) {
- throw new IOException(MODULE_INFO + " not found");
+ URI uri = options.jmodFile.toUri();
+ ModuleReference mref = new ModuleReference(descriptor, uri, new Supplier<>() {
+ @Override
+ public ModuleReader get() {
+ throw new UnsupportedOperationException();
}
+ });
- ModuleDescriptor descriptor;
- try (InputStream in = miSupplier.get()) {
- descriptor = ModuleDescriptor.read(in);
- }
+ // compose a module finder with the module path and also
+ // a module finder that can find the jmod file being created
+ ModuleFinder finder = ModuleFinder.compose(options.moduleFinder,
+ new ModuleFinder() {
+ @Override
+ public Optional<ModuleReference> find(String name) {
+ if (descriptor.name().equals(name))
+ return Optional.of(mref);
+ else return Optional.empty();
+ }
- URI uri = options.jmodFile.toUri();
- ModuleReference mref = new ModuleReference(descriptor, uri, new Supplier<>() {
@Override
- public ModuleReader get() {
- throw new UnsupportedOperationException();
+ public Set<ModuleReference> findAll() {
+ return Collections.singleton(mref);
}
});
- // compose a module finder with the module path and also
- // a module finder that can find the jmod file being created
- ModuleFinder finder = ModuleFinder.compose(options.moduleFinder,
- new ModuleFinder() {
- @Override
- public Optional<ModuleReference> find(String name) {
- if (descriptor.name().equals(name))
- return Optional.of(mref);
- else return Optional.empty();
- }
-
- @Override
- public Set<ModuleReference> findAll() {
- return Collections.singleton(mref);
- }
- });
-
- return new Hasher(finder);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
+ return new Hasher(finder);
}
/**
@@ -617,7 +605,7 @@
String toPackageName(ZipEntry entry) {
String name = entry.getName();
assert name.endsWith(".class");
- int index = name.lastIndexOf("/");
+ int index = name.lastIndexOf('/');
if (index != -1)
return name.substring(0, index).replace('/', '.');
else
@@ -714,7 +702,7 @@
public boolean test(JarEntry je) {
String name = je.getName();
// ## no support for excludes. Is it really needed?
- return !name.endsWith(MODULE_INFO) && !je.isDirectory();
+ return !je.isDirectory() && !name.endsWith(MODULE_INFO);
}
}
}
More information about the jigsaw-dev
mailing list