diff --git a/platform/core.startup/src/org/netbeans/core/startup/ModuleList.java b/platform/core.startup/src/org/netbeans/core/startup/ModuleList.java index e1595f153ea2..67e22314f568 100644 --- a/platform/core.startup/src/org/netbeans/core/startup/ModuleList.java +++ b/platform/core.startup/src/org/netbeans/core/startup/ModuleList.java @@ -24,13 +24,12 @@ import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.CharArrayWriter; +import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PushbackInputStream; @@ -51,6 +50,7 @@ import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import org.netbeans.DuplicateException; import org.netbeans.Events; import org.netbeans.InvalidException; @@ -111,7 +111,7 @@ final class ModuleList implements Stamps.Updater { /** to fire events with */ private final Events ev; /** map from code name (base)s to statuses of modules on disk */ - private final Map statuses = new HashMap(100); + private final Map statuses = new HashMap<>(100); /** whether the initial round has been triggered or not */ private boolean triggered = false; /** listener for changes in modules, etc.; see comment on class Listener */ @@ -197,8 +197,7 @@ private File findJarByName(String jar, String name) throws IOException { for (File candidate : jars) { int candidateMajor = -1; SpecificationVersion candidateSpec = null; - JarFile jf = new JarFile(candidate); - try { + try (JarFile jf = new JarFile(candidate)) { java.util.jar.Attributes attr = jf.getManifest().getMainAttributes(); String codename = attr.getValue("OpenIDE-Module"); if (codename != null) { @@ -211,8 +210,6 @@ private File findJarByName(String jar, String name) throws IOException { if (sv != null) { candidateSpec = new SpecificationVersion(sv); } - } finally { - jf.close(); } if (newest == null || candidateMajor > major || (spec != null && candidateSpec != null && candidateSpec.compareTo(spec) > 0)) { newest = candidate; @@ -434,7 +431,10 @@ private Object processStatusParam(String k, String v) throws NumberFormatExcepti /** Just checks that all the right stuff is there. */ - private void sanityCheckStatus(Map m) throws IOException { + private static void sanityCheckStatus(Map m) throws IOException { + if (m.isEmpty()) { + throw new IOException("Must define properties"); // NOI18N + } String jar = (String) m.get("jar"); // NOI18N if (jar == null) { throw new IOException("Must define jar param"); // NOI18N @@ -612,7 +612,7 @@ private String readTo(InputStream is, char delim) throws IOException { } } - final Map> readCache() { + final Map> readCache() { InputStream is = Stamps.getModulesJARs().asStream("all-modules.dat"); // NOI18N if (is == null) { // schedule write for later @@ -620,30 +620,14 @@ final Map> readCache() { return null; } LOG.log(Level.FINEST, "Reading cache all-modules.dat"); - try { - ObjectInputStream ois = new ObjectInputStream(is); - - Map> ret = new HashMap>(1333); - while (is.available() > 0) { - Map prop = readStatus(ois, false); - if (prop == null) { - LOG.log(Level.CONFIG, "Cache is invalid all-modules.dat"); - return null; - } - Set deps; - try { - deps = (Set) ois.readObject(); - } catch (ClassNotFoundException ex) { - throw new IOException(ex); - } - prop.put("deps", deps); - String cnb = (String)prop.get("name"); // NOI18N - ret.put(cnb, prop); + try (DataInputStream dis = new DataInputStream(is)) { + Map> cache = new HashMap<>(1333); + while (dis.available() > 0) { + Map props = readProps(dis); + props.put("deps", readDeps(dis)); + cache.put((String) props.get("name"), props); } - - - is.close(); - return ret; + return cache; } catch (IOException ex) { LOG.log(Level.INFO, "Cannot read cache", ex); writeCache(); @@ -651,6 +635,41 @@ final Map> readCache() { } } + private static Set readDeps(DataInputStream is) throws IOException { + int depCount = is.readInt(); + if (depCount < 0) { + throw new IOException("negative count"); + } else if (depCount == 0) { + return Set.of(); + } + Set deps = new HashSet<>((int) Math.ceil(depCount / 0.75)); + for (int i = 0; i < depCount; i++) { + deps.add(Dependency.read(is)); + } + return deps; + } + + private static Map readProps(DataInputStream is) throws IOException { + Map props = new HashMap<>(8); + for (String str : is.readUTF().split(",")) { + String[] entry = str.split("=", 2); + // must match computeProperties() + try { + Object val = switch (entry[0]) { + case "name", "jar" -> entry[1]; + case "enabled", "autoload", "eager", "reloadable" -> Boolean.valueOf(entry[1]); + case "startlevel" -> Integer.valueOf(entry[1]); + default -> throw new IOException("unknown key " + entry[0]); + }; + props.put(entry[0], val); + } catch (IllegalArgumentException | ArrayIndexOutOfBoundsException ex) { + throw new IOException("unexpected value", ex); + } + } + sanityCheckStatus(props); + return props; + } + final void writeCache() { Stamps.getModulesJARs().scheduleSave(this, "all-modules.dat", false); } @@ -661,14 +680,23 @@ public void cacheReady() { @Override public void flushCaches(DataOutputStream os) throws IOException { - ObjectOutputStream oss = new ObjectOutputStream(os); for (Module m : mgr.getModules()) { if (m.isFixed()) { continue; } - Map prop = computeProperties(m); - writeStatus(prop, oss); - oss.writeObject(m.getDependencies()); + // props + String list = computeProperties(m).entrySet() + .stream() + .map(e -> e.getKey() + "=" + e.getValue()) + .collect(Collectors.joining(",")); + os.writeUTF(list); + + // deps + Set deps = m.getDependencies(); + os.writeInt(deps.size()); + for (Dependency dep : deps) { + dep.write(os); + } } } @@ -694,7 +722,7 @@ private void writeStatus(Map m, OutputStream os) throws IOExcept // Use TreeMap to sort the keys by name; since the module status files might // be version-controlled we want to avoid gratuitous format changes. - for (Map.Entry entry: new TreeMap(m).entrySet()) { + for (Map.Entry entry : new TreeMap<>(m).entrySet()) { String name = entry.getKey(); if ( name.equals("name") || // NOI18N @@ -749,11 +777,8 @@ public void run() throws IOException { LOG.fine("ModuleList: (re)writing " + nue.file); FileLock lock = nue.file.lock(); try { - OutputStream os = nue.file.getOutputStream(lock); - try { + try (OutputStream os = nue.file.getOutputStream(lock)) { writeStatus(nue.diskProps, os); - } finally { - os.close(); } } finally { lock.releaseLock(); @@ -944,12 +969,13 @@ private void moduleChanged(Module m, DiskStatus status) { } } - /** Compute what properties we would want to store in XML + /** + * Compute what properties we would want to store in XML (or the startup cache) * for this module. I.e. 'name', 'reloadable', etc. */ - private Map computeProperties(Module m) { + private Map computeProperties(Module m) { if (m.isFixed() || ! m.isValid()) throw new IllegalArgumentException("fixed or invalid: " + m); // NOI18N - Map p = new HashMap(); + Map p = new HashMap<>(8); p.put("name", m.getCodeNameBase()); // NOI18N if (!m.isAutoload() && !m.isEager()) { p.put("enabled", m.isEnabled()); // NOI18N @@ -960,8 +986,7 @@ private Map computeProperties(Module m) { if (m.getStartLevel() > 0) { p.put("startlevel", m.getStartLevel()); // NOI18N } - if (m.getHistory() instanceof ModuleHistory) { - ModuleHistory hist = (ModuleHistory) m.getHistory(); + if (m.getHistory() instanceof ModuleHistory hist) { p.put("jar", hist.getJar()); // NOI18N } return p; @@ -990,6 +1015,7 @@ private final class Listener implements PropertyChangeListener, ErrorHandler, En // Property change coming from ModuleManager or some known Module. private boolean listening = true; + @Override public void propertyChange(PropertyChangeEvent evt) { if (! triggered) throw new IllegalStateException("Property change before trigger()"); // NOI18N // REMEMBER this is inside *read* mutex, it is forbidden to even attempt @@ -1036,15 +1062,19 @@ public void propertyChange(PropertyChangeEvent evt) { // SAX stuff. + @Override public void warning(SAXParseException e) throws SAXException { LOG.log(Level.WARNING, null, e); } + @Override public void error(SAXParseException e) throws SAXException { throw e; } + @Override public void fatalError(SAXParseException e) throws SAXException { throw e; } + @Override public InputSource resolveEntity(String pubid, String sysid) throws SAXException, IOException { if (pubid.equals(PUBLIC_ID)) { if (VALIDATE_XML) { @@ -1062,6 +1092,7 @@ public InputSource resolveEntity(String pubid, String sysid) throws SAXException // Changes in Modules/ folder. + @Override public void fileDeleted(FileEvent ev) { if (isOurs(ev)) { if (LOG.isLoggable(Level.FINE)) { @@ -1073,6 +1104,7 @@ public void fileDeleted(FileEvent ev) { fileDeleted0(fo.getName(), fo.getExt()/*, ev.getTime()*/); } + @Override public void fileDataCreated(FileEvent ev) { if (isOurs(ev)) { if (LOG.isLoggable(Level.FINE)) { @@ -1084,6 +1116,7 @@ public void fileDataCreated(FileEvent ev) { fileCreated0(fo.getName(), fo.getExt()/*, ev.getTime()*/); } + @Override public void fileRenamed(FileRenameEvent ev) { if (isOurs(ev)) { throw new IllegalStateException("I don't rename anything! " + ev); // NOI18N @@ -1124,6 +1157,7 @@ private void fileDeleted0(String name, String ext/*, long time*/) { } // else ignore } + @Override public void fileChanged(FileEvent ev) { if (isOurs(ev)) { if (LOG.isLoggable(Level.FINE)) { @@ -1150,9 +1184,11 @@ public void fileChanged(FileEvent ev) { } // else ignore } + @Override public void fileFolderCreated(FileEvent ev) { // ignore } + @Override public void fileAttributeChanged(FileAttributeEvent ev) { // ignore } @@ -1549,7 +1585,7 @@ public void run() { Map> cache = readCache(); String[] names; if (cache != null) { - names = cache.keySet().toArray(new String[cache.size()]); + names = cache.keySet().toArray(String[]::new); } else { FileObject[] children = folder.getChildren(); List arr = new ArrayList(children.length); @@ -1572,7 +1608,7 @@ public void run() { LOG.fine("Strange file encountered in modules folder: " + f); } } - names = arr.toArray(new String[0]); + names = arr.toArray(String[]::new); } ev.log(Events.MODULES_FILE_SCANNED, names.length); XMLReader reader = null; @@ -1635,12 +1671,12 @@ public void run() { } ModuleHistory history = new ModuleHistory(jar, "loaded from " + f); // NOI18N Boolean reloadableB = (Boolean) props.get("reloadable"); // NOI18N - boolean reloadable = reloadableB != null ? reloadableB.booleanValue() : false; - boolean enabled = enabledB != null ? enabledB.booleanValue() : false; + boolean reloadable = reloadableB != null ? reloadableB : false; + boolean enabled = enabledB != null ? enabledB : false; Boolean autoloadB = (Boolean) props.get("autoload"); // NOI18N - boolean autoload = autoloadB != null ? autoloadB.booleanValue() : false; + boolean autoload = autoloadB != null ? autoloadB : false; Boolean eagerB = (Boolean) props.get("eager"); // NOI18N - boolean eager = eagerB != null ? eagerB.booleanValue() : false; + boolean eager = eagerB != null ? eagerB : false; NbInstaller.register(name, props.get("deps")); // NOI18N Integer startLevel = (Integer)props.get("startlevel"); // NOI18N Module m = createModule(jarFile, history, reloadable, autoload, eager, startLevel); diff --git a/platform/core.startup/src/org/netbeans/core/startup/ModuleSystem.java b/platform/core.startup/src/org/netbeans/core/startup/ModuleSystem.java index 7408107ffa43..90355763b664 100644 --- a/platform/core.startup/src/org/netbeans/core/startup/ModuleSystem.java +++ b/platform/core.startup/src/org/netbeans/core/startup/ModuleSystem.java @@ -19,7 +19,6 @@ package org.netbeans.core.startup; -import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; @@ -84,11 +83,9 @@ public ModuleSystem(FileSystem systemFileSystem) throws IOException { final void init(FileSystem systemFileSystem) throws IOException { if (Boolean.getBoolean("org.netbeans.core.startup.ModuleSystem.CULPRIT")) Thread.dumpStack(); // NOI18N - PropertyChangeListener l = new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent ev) { - if (ModuleManager.PROP_CLASS_LOADER.equals(ev.getPropertyName())) { - org.netbeans.core.startup.MainLookup.systemClassLoaderChanged(mgr.getClassLoader()); - } + PropertyChangeListener l = (evt) -> { + if (ModuleManager.PROP_CLASS_LOADER.equals(evt.getPropertyName())) { + org.netbeans.core.startup.MainLookup.systemClassLoaderChanged(mgr.getClassLoader()); } }; mgr.addPropertyChangeListener(l); @@ -135,7 +132,7 @@ public Events getEvents() { public List getModuleJars () { mgr.mutexPrivileged().enterReadAccess(); try { - List l = new ArrayList(); + List l = new ArrayList<>(); for (Module m: mgr.getEnabledModules()) { l.addAll(m.getAllJars()); } @@ -158,7 +155,7 @@ public void loadBootModules() { // Keep a list of manifest URL bases which we know we do not need to // parse. Some of these manifests might be signed, and if so, we do not // want to touch them, as it slows down startup quite a bit. - Set ignoredJars = new HashSet(); + Set ignoredJars = new HashSet<>(); String javaHome = System.getProperty("java.home"); // NOI18N if (javaHome != null) { File lib = new File(new File(javaHome).getParentFile(), "lib"); // NOI18N @@ -173,7 +170,7 @@ public void loadBootModules() { mgr.mutexPrivileged().enterWriteAccess(); ev.log(Events.START_LOAD_BOOT_MODULES); try { - bootModules = new HashSet(10); + bootModules = new HashSet<>(10); ClassLoader upperLoader = ModuleSystem.class.getClassLoader(); // wrap alien loader, so it can be used among parent loaders of module (instanceof ProxyClassLoader) ClassLoader loader = new JarClassLoader(Collections.emptyList(), new ClassLoader[] { Module.class.getClassLoader() }); @@ -183,7 +180,7 @@ public void loadBootModules() { ev.log(Events.PERF_TICK, "got all manifests"); // NOI18N // There will be duplicates: cf. #32576. - Set checkedManifests = new HashSet(); + Set checkedManifests = new HashSet<>(); // process libs in 2 passes; first, process bootstrap libraries in platform/libs, creating // FixedModules with a classloader that only loads from those libs. @@ -284,16 +281,16 @@ public void readList() { } finally { mgr.mutexPrivileged().exitWriteAccess(); } - ev.log(Events.PERF_END, "ModuleSystem.readList"); // NOI18N + ev.log(Events.PERF_END, "ModuleSystem.readList"); // NOI18N } /** Install read modules. */ public void restore() { - ev.log(Events.PERF_START, "ModuleSystem.restore"); // NOI18N + ev.log(Events.PERF_START, "ModuleSystem.restore"); // NOI18N mgr.mutexPrivileged().enterWriteAccess(); try { - Set toTrigger = new HashSet(bootModules/*Collections.EMPTY_SET*/); + Set toTrigger = new HashSet<>(bootModules/*Collections.EMPTY_SET*/); list.trigger(toTrigger); mgr.releaseModuleManifests(); } finally { @@ -312,9 +309,7 @@ public void restore() { public boolean shutDown(final Runnable midHook) { try { return shutDownAsync(midHook).get(); - } catch (InterruptedException ex) { - Exceptions.printStackTrace(ex); - } catch (ExecutionException ex) { + } catch (InterruptedException | ExecutionException ex) { Exceptions.printStackTrace(ex); } return false; @@ -333,12 +328,9 @@ public boolean shutDown(final Runnable midHook) { */ public Future shutDownAsync(final Runnable midHook) { mgr.mutexPrivileged().enterWriteAccess(); - Runnable both = new Runnable() { - @Override - public void run() { - midHook.run(); - Stamps.getModulesJARs().shutdown(); - } + Runnable both = () -> { + midHook.run(); + Stamps.getModulesJARs().shutdown(); }; Future res; try { @@ -370,7 +362,7 @@ final void deployTestModule(File jar) throws IOException { // The test module: Module tm = null; // Anything that needs to be turned back on later: - Set toReenable = new HashSet(); + Set toReenable = new HashSet<>(); // First see if this refers to an existing module. // (If so, make sure it is reloadable.) for (Module m : mgr.getModules()) { @@ -406,7 +398,7 @@ final void deployTestModule(File jar) throws IOException { tm = mgr.create(jar, new ModuleHistory(jar.getAbsolutePath()), true, false, false); } catch (DuplicateException dupe2) { // Should not happen. - throw (IOException) new IOException(dupe2.toString()).initCause(dupe2); + throw new IOException(dupe2); } } } @@ -514,6 +506,7 @@ public static void markForRestart() throws UnsupportedOperationException { */ private static final class QuietEvents extends Events { QuietEvents() {} + @Override protected void logged(String message, Object[] args) {} } diff --git a/platform/o.n.bootstrap/src/org/netbeans/Module.java b/platform/o.n.bootstrap/src/org/netbeans/Module.java index ff81bba3e10a..c040a503f8ce 100644 --- a/platform/o.n.bootstrap/src/org/netbeans/Module.java +++ b/platform/o.n.bootstrap/src/org/netbeans/Module.java @@ -20,17 +20,19 @@ package org.netbeans; import java.io.DataInput; +import java.io.DataInputStream; import java.io.DataOutput; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.ObjectInput; -import java.io.ObjectInputStream; -import java.io.ObjectOutput; -import java.lang.reflect.Method; import java.net.URL; import java.security.CodeSource; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; @@ -80,7 +82,7 @@ public abstract class Module extends ModuleInfo { private ModuleData data; private NbInstrumentation instr; - private static final Object DATA_LOCK = new Object(); + private final Object DATA_LOCK = new Object(); /** Use ModuleManager.create as a factory. */ protected Module(ModuleManager mgr, Events ev, Object history, boolean reloadable, boolean autoload, boolean eager) throws IOException { @@ -115,7 +117,7 @@ protected Module(ModuleManager mgr, Events ev, Object history, ClassLoader class enabled = false; } - ModuleData createData(ObjectInput in, Manifest mf) throws IOException { + ModuleData createData(DataInput in, Manifest mf) throws IOException { if (in != null) { return new ModuleData(in); } else { @@ -123,7 +125,7 @@ ModuleData createData(ObjectInput in, Manifest mf) throws IOException { } } - final void writeData(ObjectOutput out) throws IOException { + final void writeData(DataOutput out) throws IOException { data().write(out); } @@ -136,6 +138,9 @@ final ModuleData data() { } final ModuleData dataWithCheck() throws InvalidException { + if (data != null) { + return data; + } synchronized (DATA_LOCK) { if (data != null) { return data; @@ -143,10 +148,8 @@ final ModuleData dataWithCheck() throws InvalidException { Util.err.log(Level.FINE, "Initialize data {0}", getJarFile()); // NOI18N InputStream is = mgr.dataFor(getJarFile()); if (is != null) { - try { - ObjectInputStream ois = new ObjectInputStream(is); + try (DataInputStream ois = new DataInputStream(is)) { ModuleData mine = createData(ois, null); - ois.close(); assert data == null; data = mine; return mine; @@ -286,8 +289,9 @@ public final boolean provides(String token) { @Override public Set getDependencies() { - return new HashSet(Arrays.asList(getDependenciesArray())); + return new HashSet<>(Arrays.asList(getDependenciesArray())); } + public final Dependency[] getDependenciesArray() { Dependency[] dependenciesA; try { @@ -317,8 +321,8 @@ public String getBuildVersion() { public @Override boolean owns(Class clazz) { ClassLoader cl = clazz.getClassLoader(); - if (cl instanceof Util.ModuleProvider) { - return ((Util.ModuleProvider) cl).getModule() == this; + if (cl instanceof Util.ModuleProvider mp) { + return mp.getModule() == this; } if (cl != classloader) { return false; @@ -341,11 +345,8 @@ static String findClasspathModuleCodeName(Class clazz) { loc = new URL("jar:" + loc + "!/"); } URL manifest = new URL(loc, "META-INF/MANIFEST.MF"); - InputStream is = manifest.openStream(); - try { + try (InputStream is = manifest.openStream()) { return new Manifest(is).getMainAttributes().getValue("OpenIDE-Module"); - } finally { - is.close(); } } catch (IOException x) { Logger.getLogger(Module.class.getName()).log(Level.FINE, null, x); @@ -500,7 +501,7 @@ public void releaseManifest() {} public Set getProblems() { // cannot use Union2 without being binary-incompatible if (! isValid()) throw new IllegalStateException("Not valid: " + this); // NOI18N if (isEnabled()) return Collections.emptySet(); - Set problems = new HashSet(); + Set problems = new HashSet<>(); for (Union2 problem : mgr.missingDependencies(this)) { if (problem.hasFirst()) { problems.add(problem.first()); @@ -561,8 +562,8 @@ public Enumeration findResources(String resources) { try { // #149136 ClassLoader cl = getClassLoader(); - if (cl instanceof ProxyClassLoader) { - return ((ProxyClassLoader) cl).findResources(resources); + if (cl instanceof ProxyClassLoader pcl) { + return pcl.findResources(resources); } //TODO: other ClassLoaders - what can we expect here? can fallback to getResources for JVM classloaders, and nothing else should be here? throw new IllegalStateException("Unexpected ClassLoader: " + cl + "."); diff --git a/platform/o.n.bootstrap/src/org/netbeans/ModuleData.java b/platform/o.n.bootstrap/src/org/netbeans/ModuleData.java index 9e9f32710eee..a2eca1ef8f28 100644 --- a/platform/o.n.bootstrap/src/org/netbeans/ModuleData.java +++ b/platform/o.n.bootstrap/src/org/netbeans/ModuleData.java @@ -21,8 +21,6 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -91,7 +89,7 @@ class ModuleData { if (verifyCNBs) { Dependency.create(Dependency.TYPE_MODULE, codeName); } - codeNameRelease = (cnParse[1] != null) ? ((Integer) cnParse[1]).intValue() : -1; + codeNameRelease = (cnParse[1] != null) ? (Integer) cnParse[1] : -1; if (cnParse[2] != null) { throw new NumberFormatException(codeName); } @@ -120,7 +118,7 @@ class ModuleData { publicPackages = ZERO_PACKAGE_ARRAY; } else { StringTokenizer tok = new StringTokenizer(exportsS, ", "); // NOI18N - List exports = new ArrayList(Math.max(tok.countTokens(), 1)); + List exports = new ArrayList<>(Math.max(tok.countTokens(), 1)); while (tok.hasMoreTokens()) { String piece = tok.nextToken(); if (piece.endsWith(".*")) { // NOI18N @@ -148,7 +146,7 @@ class ModuleData { if (exports.isEmpty()) { throw new IllegalArgumentException("Illegal OpenIDE-Module-Public-Packages: " + exportsS); // NOI18N } - publicPackages = exports.toArray(new Module.PackageExport[0]); + publicPackages = exports.toArray(Module.PackageExport[]::new); } } else { // XXX new link? @@ -166,7 +164,7 @@ class ModuleData { String friends = attr.getValue("OpenIDE-Module-Friends"); // NOI18N if (friends != null) { StringTokenizer tok = new StringTokenizer(friends, ", "); // NOI18N - set = new HashSet(); + set = new HashSet<>(); while (tok.hasMoreTokens()) { String piece = tok.nextToken(); if (piece.indexOf('/') != -1) { @@ -209,7 +207,7 @@ class ModuleData { } catch (IllegalArgumentException iae) { throw (InvalidException) new InvalidException("While parsing " + codeName + " a dependency attribute: " + iae.toString()).initCause(iae); // NOI18N } - this.coveredPackages = new HashSet(); + this.coveredPackages = new HashSet<>(); this.agentClass = attr.getValue("Agent-Class"); } @@ -242,41 +240,53 @@ class ModuleData { this.publicPackages = null; this.provides = computeProvides(m, mf.getMainAttributes(), false, true); this.dependencies = computeImported(mf.getMainAttributes()); - this.coveredPackages = new HashSet(); + this.coveredPackages = new HashSet<>(); this.agentClass = getMainAttribute(mf, "Agent-Class"); // NOI18N this.fragmentHostCodeName = null; } - ModuleData(ObjectInput dis) throws IOException { - try { - this.codeName = dis.readUTF(); - this.codeNameBase = dis.readUTF(); - this.codeNameRelease = dis.readInt(); - this.coveredPackages = readStrings(dis, new HashSet(), true); - this.dependencies = (Dependency[]) dis.readObject(); - this.implVersion = dis.readUTF(); - this.buildVersion = dis.readUTF(); - this.provides = readStrings(dis); - this.friendNames = readStrings(dis, new HashSet(), false); - this.specVers = new SpecificationVersion(dis.readUTF()); - this.publicPackages = Module.PackageExport.read(dis); - this.agentClass = dis.readUTF(); - String s = dis.readUTF(); - if (s != null) { - s = s.trim(); - } - this.fragmentHostCodeName = s == null || s.isEmpty() ? null : s; - } catch (ClassNotFoundException cnfe) { - throw new IOException(cnfe); + ModuleData(DataInput dis) throws IOException { + this.codeName = dis.readUTF(); + this.codeNameBase = dis.readUTF(); + this.codeNameRelease = dis.readInt(); + this.coveredPackages = readStrings(dis, new HashSet<>(), true); + this.dependencies = readDeps(dis); + this.implVersion = dis.readUTF(); + this.buildVersion = dis.readUTF(); + this.provides = readStrings(dis); + this.friendNames = readStrings(dis, new HashSet<>(), false); + this.specVers = new SpecificationVersion(dis.readUTF()); + this.publicPackages = Module.PackageExport.read(dis); + this.agentClass = dis.readUTF(); + String s = dis.readUTF(); + if (s != null) { + s = s.trim(); + } + this.fragmentHostCodeName = s == null || s.isEmpty() ? null : s; + } + + private static Dependency[] readDeps(DataInput dis) throws IOException { + int count = Math.max(dis.readInt(), 0); + Dependency[] deps = new Dependency[count]; + for (int i = 0; i < deps.length; i++) { + deps[i] = Dependency.read(dis); } + return deps; } - void write(ObjectOutput dos) throws IOException { + void write(DataOutput dos) throws IOException { dos.writeUTF(codeName); dos.writeUTF(codeNameBase); dos.writeInt(codeNameRelease); writeStrings(dos, coveredPackages); - dos.writeObject(dependencies); + if (dependencies == null) { + dos.writeInt(0); + } else { + dos.writeInt(dependencies.length); + for (Dependency dep : dependencies) { + dep.write(dos); + } + } dos.writeUTF(implVersion); dos.writeUTF(buildVersion); writeStrings(dos, provides); @@ -291,7 +301,7 @@ private Dependency[] computeImported(Attributes attr) { String pkgs = attr.getValue("Import-Package"); // NOI18N List arr = null; if (pkgs != null) { - arr = new ArrayList(); + arr = new ArrayList<>(); StringTokenizer tok = createTokenizer(pkgs); // NOI18N while (tok.hasMoreElements()) { String dep = beforeSemicolon(tok); @@ -301,7 +311,7 @@ private Dependency[] computeImported(Attributes attr) { String recomm = attr.getValue("Require-Bundle"); // NOI18N if (recomm != null) { if (arr == null) { - arr = new ArrayList(); + arr = new ArrayList<>(); } StringTokenizer tok = createTokenizer(recomm); // NOI18N while (tok.hasMoreElements()) { @@ -309,7 +319,7 @@ private Dependency[] computeImported(Attributes attr) { arr.addAll(Dependency.create(Dependency.TYPE_RECOMMENDS, "cnb." + dep)); // NOI18N } } - return arr == null ? null : arr.toArray(new Dependency[0]); + return arr == null ? null : arr.toArray(Dependency[]::new); } private static StringTokenizer createTokenizer(String osgiDep) { @@ -355,7 +365,7 @@ private String[] computeExported(boolean useOSGi, Collection arr, Attrib private String[] computeProvides( Module forModule, Attributes attr, boolean verifyCNBs, boolean useOSGi ) throws InvalidException, IllegalArgumentException { - Set arr = new LinkedHashSet(); + Set arr = new LinkedHashSet<>(); // Token provides String providesS = attr.getValue("OpenIDE-Module-Provides"); // NOI18N if (providesS != null) { @@ -394,11 +404,11 @@ private String[] computeProvides( private Dependency[] initDeps(Module forModule, Set knownDeps, Attributes attr) throws IllegalStateException, IllegalArgumentException { if (knownDeps != null) { - return knownDeps.toArray(new Dependency[0]); + return knownDeps.toArray(Dependency[]::new); } // deps - Set deps = new HashSet(20); + Set deps = new HashSet<>(20); // First convert IDE/1 -> org.openide/1, so we never have to deal with // "IDE deps" internally: @SuppressWarnings(value = "deprecation") @@ -428,7 +438,7 @@ private Dependency[] initDeps(Module forModule, Set knownDeps, Attributes att deps.addAll(Dependency.create(Dependency.TYPE_NEEDS, attr.getValue("OpenIDE-Module-Needs"))); // NOI18N deps.addAll(Dependency.create(Dependency.TYPE_RECOMMENDS, attr.getValue("OpenIDE-Module-Recommends"))); // NOI18N forModule.refineDependencies(deps); - return deps.toArray(new Dependency[0]); + return deps.toArray(Dependency[]::new); } final String getFragmentHostCodeName() { @@ -496,13 +506,12 @@ private > T readStrings( } return set; } - private String[] readStrings(ObjectInput dis) throws IOException { - List arr = new ArrayList(); + private String[] readStrings(DataInput dis) throws IOException { + List arr = new ArrayList<>(); readStrings(dis, arr, false); - return arr.toArray(new String[0]); + return arr.toArray(String[]::new); } - private void writeStrings(DataOutput dos, Collection set) - throws IOException { + private void writeStrings(DataOutput dos, Collection set) throws IOException { if (set == null) { dos.writeInt(0); return; @@ -512,7 +521,7 @@ private void writeStrings(DataOutput dos, Collection set) dos.writeUTF(s); } } - private void writeStrings(ObjectOutput dos, String[] provides) throws IOException { + private void writeStrings(DataOutput dos, String[] provides) throws IOException { writeStrings(dos, Arrays.asList(provides)); } diff --git a/platform/o.n.bootstrap/src/org/netbeans/ModuleManager.java b/platform/o.n.bootstrap/src/org/netbeans/ModuleManager.java index 615b59c6069e..01bf8a1d6d80 100644 --- a/platform/o.n.bootstrap/src/org/netbeans/ModuleManager.java +++ b/platform/o.n.bootstrap/src/org/netbeans/ModuleManager.java @@ -29,7 +29,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.ObjectOutputStream; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.net.URL; @@ -1272,10 +1271,10 @@ public void enable(Set modules) throws IllegalArgumentException, Invalid * from other objects, that can't be compatibly passed 'willEnable' info. */ static class EnableContext { - final List willEnable; + final Set willEnable; public EnableContext(List willEnable) { - this.willEnable = willEnable; + this.willEnable = new HashSet<>(willEnable); } } @@ -2546,9 +2545,9 @@ public void flushCaches(DataOutputStream os) throws IOException { os.writeUTF(m.getCodeNameBase()); ByteArrayOutputStream data = new ByteArrayOutputStream(); - ObjectOutputStream dos = new ObjectOutputStream(data); - m.writeData(dos); - dos.close(); + try (DataOutputStream dos = new DataOutputStream(data)) { + m.writeData(dos); + } byte[] arr = data.toByteArray(); os.writeInt(arr.length); diff --git a/platform/o.n.bootstrap/src/org/netbeans/NetigsoModule.java b/platform/o.n.bootstrap/src/org/netbeans/NetigsoModule.java index 29eb2aea9bcf..63f9466d02a8 100644 --- a/platform/o.n.bootstrap/src/org/netbeans/NetigsoModule.java +++ b/platform/o.n.bootstrap/src/org/netbeans/NetigsoModule.java @@ -19,9 +19,9 @@ package org.netbeans; +import java.io.DataInput; import java.io.File; import java.io.IOException; -import java.io.ObjectInput; import java.net.URL; import java.util.Collections; import java.util.Enumeration; @@ -30,7 +30,6 @@ import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; -import org.openide.util.Enumerations; import org.openide.util.Exceptions; /** Special module for representing OSGi bundles @@ -51,7 +50,7 @@ public NetigsoModule(Manifest mani, File jar, ModuleManager mgr, Events ev, Obje } @Override - ModuleData createData(ObjectInput in, Manifest mf) throws IOException { + ModuleData createData(DataInput in, Manifest mf) throws IOException { if (in != null) { return new ModuleData(in); } else { diff --git a/platform/o.n.bootstrap/src/org/netbeans/Stamps.java b/platform/o.n.bootstrap/src/org/netbeans/Stamps.java index b5b083a8efbd..fc926d682e76 100644 --- a/platform/o.n.bootstrap/src/org/netbeans/Stamps.java +++ b/platform/o.n.bootstrap/src/org/netbeans/Stamps.java @@ -46,7 +46,6 @@ import java.util.List; import java.util.Locale; import java.util.Random; -import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -183,8 +182,7 @@ private ByteBuffer asByteBuffer(String cache, boolean direct, boolean mmap) { return null; } - try { - FileChannel fc = new FileInputStream(cacheFile).getChannel(); + try (FileChannel fc = new FileInputStream(cacheFile).getChannel()) { ByteBuffer master; if (mmap) { master = fc.map(FileChannel.MapMode.READ_ONLY, 0, len[0]); @@ -198,9 +196,6 @@ private ByteBuffer asByteBuffer(String cache, boolean direct, boolean mmap) { } master.flip(); } - - fc.close(); - return master; } catch (IOException ex) { LOG.log(Level.WARNING, "Cannot read cache " + cacheFile, ex); // NOI18N @@ -309,17 +304,16 @@ private static AtomicLong stamp(boolean checkStampFile) { private static void stamp(boolean checkStampFile, AtomicLong result, AtomicReference newestFile) { StringBuilder sb = new StringBuilder(); - Set processedDirs = new HashSet(); String[] relativeDirs = Clusters.relativeDirsWithHome(); String home = System.getProperty ("netbeans.home"); // NOI18N if (home != null) { - long stamp = stampForCluster (new File (home), result, newestFile, processedDirs, checkStampFile, true, null); + long stamp = stampForCluster (new File (home), result, newestFile, checkStampFile, true, null); sb.append(relativeDirs[0]).append('=').append(stamp).append('\n'); } String[] drs = Clusters.dirs(); for (int i = 0; i < drs.length; i++) { final File clusterDir = new File(drs[i]); - long stamp = stampForCluster(clusterDir, result, newestFile, processedDirs, checkStampFile, true, null); + long stamp = stampForCluster(clusterDir, result, newestFile, checkStampFile, true, null); if (stamp != -1) { sb.append("cluster.").append(relativeDirs[i + 1]).append('=').append(stamp).append('\n'); } @@ -327,7 +321,7 @@ private static void stamp(boolean checkStampFile, AtomicLong result, AtomicRefer File user = Places.getUserDirectory(); if (user != null) { AtomicInteger crc = new AtomicInteger(); - stampForCluster(user, result, newestFile, new HashSet(), false, false, crc); + stampForCluster(user, result, newestFile, false, false, crc); sb.append("user=").append(result.longValue()).append('\n'); sb.append("crc=").append(crc.intValue()).append('\n'); sb.append("locale=").append(Locale.getDefault()).append('\n'); @@ -352,7 +346,7 @@ observed to contain absolute paths to the NetBeans install directory (netbeans.h } private static long stampForCluster( - File cluster, AtomicLong result, AtomicReference newestFile, Set hashSet, + File cluster, AtomicLong result, AtomicReference newestFile, boolean checkStampFile, boolean createStampFile, AtomicInteger crc ) { File stamp = new File(cluster, ".lastModified"); // NOI18N @@ -436,12 +430,10 @@ private static boolean compareAndUpdateFile(File file, String content, AtomicLon try { byte[] expected = content.getBytes(StandardCharsets.UTF_8); byte[] read = new byte[expected.length]; - FileInputStream is = null; boolean areCachesOK; boolean writeFile; long lastMod; - try { - is = new FileInputStream(file); + try (FileInputStream is = new FileInputStream(file)) { int len = is.read(read); areCachesOK = len == read.length && is.available() == 0 && Arrays.equals(expected, read); writeFile = !areCachesOK; @@ -451,16 +443,12 @@ private static boolean compareAndUpdateFile(File file, String content, AtomicLon areCachesOK = true; writeFile = true; lastMod = result.get(); - } finally { - if (is != null) { - is.close(); - } } if (writeFile) { file.getParentFile().mkdirs(); - FileOutputStream os = new FileOutputStream(file); - os.write(expected); - os.close(); + try (FileOutputStream os = new FileOutputStream(file)) { + os.write(expected); + } if (areCachesOK) { file.setLastModified(lastMod); } @@ -492,7 +480,6 @@ private static void deleteCache(File cacheFile) throws IOException { LOG.log(Level.INFO, "cannot rename (#{0}): {1}", new Object[]{i, cacheFile}); // NOI18N // try harder System.gc(); - System.runFinalization(); LOG.info("after GC"); // NOI18N if (r == null) { r = new Random(); @@ -558,12 +545,8 @@ static void checkPopulateCache() { if (is == null) { return; } - ZipInputStream zip = null; - FileOutputStream os = null; - try { - byte[] arr = new byte[4096]; + try (ZipInputStream zip = new ZipInputStream(is)) { LOG.log(Level.FINE, "Found populate.zip about to extract it into {0}", cache); - zip = new ZipInputStream(is); for (;;) { ZipEntry en = zip.getNextEntry(); if (en == null) { @@ -574,17 +557,10 @@ static void checkPopulateCache() { } File f = new File(cache, en.getName().replace('/', File.separatorChar)); f.getParentFile().mkdirs(); - os = new FileOutputStream(f); - for (;;) { - int len = zip.read(arr); - if (len == -1) { - break; - } - os.write(arr, 0, len); + try (FileOutputStream os = new FileOutputStream(f)) { + zip.transferTo(os); } - os.close(); } - zip.close(); } catch (IOException ex) { LOG.log(Level.INFO, "Failed to populate {0}", cache); } @@ -598,22 +574,12 @@ private static boolean clustersChanged() { final String clustersCache = "all-clusters.dat"; // NOI18N File f = fileImpl(clustersCache, null, -1); // no timestamp check if (f != null) { - DataInputStream dis = null; - try { - dis = new DataInputStream(new FileInputStream(f)); + try (DataInputStream dis = new DataInputStream(new FileInputStream(f))) { if (Clusters.compareDirs(dis)) { return false; } } catch (IOException ex) { return clustersChanged = true; - } finally { - if (dis != null) { - try { - dis.close(); - } catch (IOException ex) { - LOG.log(Level.INFO, null, ex); - } - } } } else { // missing cluster file signals caches are OK, for @@ -708,12 +674,10 @@ public boolean store(AtomicInteger delay) { LOG.log(Level.FINE, "Storing cache {0}", cacheFile); os = new FileOutputStream(cacheFile, append); //append new entries only - DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(this, 1024 * 1024)); - - this.delay = delay; - - updater.flushCaches(dos); - dos.close(); + try (DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(this, 1024 * 1024))) { + this.delay = delay; + updater.flushCaches(dos); + } LOG.log(Level.FINE, "Done Storing cache {0}", cacheFile); } catch (IOException ex) { LOG.log(Level.WARNING, "Error saving cache {0}", cacheFile); @@ -953,8 +917,7 @@ static void writeRelativePath(String path, DataOutput dos) throws IOException { private static void produceRelativePath(String path, Object out) throws IOException { if (path.isEmpty()) { - if (out instanceof DataOutput) { - DataOutput dos = (DataOutput)out; + if (out instanceof DataOutput dos) { dos.writeUTF(path); } return; @@ -964,7 +927,7 @@ private static void produceRelativePath(String path, Object out) throws IOExcept } int cnt = 0; for (String p : Clusters.dirs()) { - if (testWritePath(path, p, "" + cnt, out)) { + if (testWritePath(path, p, Integer.toString(cnt), out)) { return; } cnt++; @@ -988,8 +951,7 @@ private static boolean testWritePath(String path, String prefix, String codeName return false; } private static void doWritePath(String codeName, String relPath, Object out) throws IOException { - if (out instanceof DataOutput) { - DataOutput dos = (DataOutput) out; + if (out instanceof DataOutput dos) { dos.writeUTF(codeName); dos.writeUTF(relPath); } else { diff --git a/platform/o.n.bootstrap/src/org/netbeans/StandardModule.java b/platform/o.n.bootstrap/src/org/netbeans/StandardModule.java index 5d770d8460be..9eb0b47f2f1b 100644 --- a/platform/o.n.bootstrap/src/org/netbeans/StandardModule.java +++ b/platform/o.n.bootstrap/src/org/netbeans/StandardModule.java @@ -24,10 +24,10 @@ // INTERACTIONS SHOULD GO ELSEWHERE. // (NbBundle.getLocalizedValue is OK here.) +import java.io.DataInput; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.ObjectInput; import java.security.AllPermission; import java.security.CodeSource; import java.security.PermissionCollection; @@ -93,7 +93,7 @@ public StandardModule(ModuleManager mgr, Events ev, File jar, Object history, bo } @Override - ModuleData createData(ObjectInput in, Manifest mf) throws IOException { + ModuleData createData(DataInput in, Manifest mf) throws IOException { if (in != null) { return new StandardModuleData(in); } else { @@ -132,6 +132,7 @@ ModuleData createData(ObjectInput in, Manifest mf) throws IOException { * explicitly suppressed from this list; should only be used for * documented localizable attributes such as OpenIDE-Module-Name etc. */ + @Override public Object getLocalizedAttribute(String attr) { String locb = getManifest().getMainAttributes().getValue("OpenIDE-Module-Localizing-Bundle"); // NOI18N boolean usingLoader = false; @@ -164,11 +165,8 @@ public Object getLocalizedAttribute(String attr) { try { // check if the jar file still exists (see issue 82480) if (jar != null && jar.isFile ()) { - JarFile jarFile = new JarFile(jar, false); - try { + try (JarFile jarFile = new JarFile(jar, false)) { loadLocalizedProps(jarFile, getManifest()); - } finally { - jarFile.close(); } } else { Util.err.log(Level.FINE, "Cannot get localized attr {0} from module {1} (missing or deleted JAR file: {2})", new Object[] {attr, getCodeNameBase(), jar}); @@ -203,6 +201,7 @@ public Object getLocalizedAttribute(String attr) { } } + @Override public boolean isFixed() { return false; } @@ -252,13 +251,10 @@ private void loadManifest() throws IOException { jarBeingOpened = physicalJar; // might be null ensurePhysicalJar(); jarBeingOpened = physicalJar; // might have changed - JarFile jarFile = new JarFile(physicalJar, false); - try { + try (JarFile jarFile = new JarFile(physicalJar, false)) { Manifest m = jarFile.getManifest(); if (m == null) throw new IOException("No manifest found in " + physicalJar); // NOI18N manifest = m; - } finally { - jarFile.close(); } } else { jarBeingOpened = jar; @@ -346,11 +342,8 @@ private void loadLocalizedProps(JarFile jarFile, Manifest m) throws IOException // May not be present in base JAR: might only be in e.g. default locale variant. if (bundleFile != null) { localizedProps = new Properties(); - InputStream is = jarFile.getInputStream(bundleFile); - try { + try (InputStream is = jarFile.getInputStream(bundleFile)) { localizedProps.load(is); - } finally { - is.close(); } } } @@ -373,23 +366,17 @@ private void loadLocalizedProps(JarFile jarFile, Manifest m) throws IOException File localeJar = pair.file; String suffix = pair.suffix; String rsrc = name + suffix + ext; - JarFile localeJarFile = new JarFile(localeJar, false); - try { + try (JarFile localeJarFile = new JarFile(localeJar, false)) { ZipEntry bundleFile = localeJarFile.getEntry(rsrc); // Need not exist in all locale variants. if (bundleFile != null) { if (localizedProps == null) { localizedProps = new Properties(); } // else append and overwrite base-locale values - InputStream is = localeJarFile.getInputStream(bundleFile); - try { + try (InputStream is = localeJarFile.getInputStream(bundleFile)) { localizedProps.load(is); - } finally { - is.close(); } } - } finally { - localeJarFile.close(); } } } @@ -437,6 +424,7 @@ public List getAllJars() { * Must be called from within a write mutex. * @param r whether the module should be considered reloadable */ + @Override public void setReloadable(boolean r) { getManager().assertWritable(); if (reloadable != r) { @@ -449,6 +437,7 @@ public void setReloadable(boolean r) { * If an exception is thrown, the module is considered * to be in an invalid state. */ + @Override public void reload() throws IOException { // Probably unnecessary but just in case: destroyPhysicalJar(); @@ -468,6 +457,7 @@ public void reload() throws IOException { /** Turn on the classloader. Passed a list of parent modules to use. * The parents should already have had their classloaders initialized. */ + @Override protected void classLoaderUp(Set parents) throws IOException { if (Util.err.isLoggable(Level.FINE)) { Util.err.fine("classLoaderUp on " + this + " with parents " + parents); @@ -533,7 +523,7 @@ protected void classLoaderUp(Set parents) throws IOException { classloader = createNewClassLoader(classp, loaders); } catch (IllegalArgumentException iae) { // Should not happen, but just in case. - throw (IOException) new IOException(iae.toString()).initCause(iae); + throw new IOException(iae); } } } @@ -551,13 +541,15 @@ protected ClassLoader getParentLoader(Module parent) { } /** Turn off the classloader and release all resources. */ + @Override protected void classLoaderDown() { - if (classloader instanceof ProxyClassLoader) { - ((ProxyClassLoader)classloader).destroy(); + if (classloader instanceof ProxyClassLoader pcl) { + pcl.destroy(); } classloader = null; } /** Should be called after turning off the classloader of one or more modules & GC'ing. */ + @Override protected void cleanup() { if (isEnabled()) throw new IllegalStateException("cleanup on enabled module: " + this); // NOI18N if (classloader != null) throw new IllegalStateException("cleanup on module with classloader: " + this); // NOI18N @@ -566,6 +558,7 @@ protected void cleanup() { } /** Notify the module that it is being deleted. */ + @Override public void destroy() { moduleJARs.remove(jar); } @@ -609,6 +602,7 @@ public OneModuleClassLoader(List classp, ClassLoader[] parents) throws Ill super(classp, parents, false, StandardModule.this); } + @Override public Module getModule() { return StandardModule.this; } @@ -681,8 +675,8 @@ public Module getModule() { return false; } Module other; - if (parent instanceof Util.ModuleProvider) { - other = ((Util.ModuleProvider)parent).getModule(); + if (parent instanceof Util.ModuleProvider mp) { + other = mp.getModule(); } else { other = null; } diff --git a/platform/o.n.bootstrap/src/org/netbeans/StandardModuleData.java b/platform/o.n.bootstrap/src/org/netbeans/StandardModuleData.java index 8ec3d96791cc..9daa11d2ba50 100644 --- a/platform/o.n.bootstrap/src/org/netbeans/StandardModuleData.java +++ b/platform/o.n.bootstrap/src/org/netbeans/StandardModuleData.java @@ -22,10 +22,8 @@ import java.io.DataOutput; import java.io.File; import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -47,7 +45,7 @@ final class StandardModuleData extends ModuleData { * different modules try to load the same extension (which would cause them * to both load their own private copy, which may not be intended). */ - private static final Map> extensionOwners = new HashMap>(); + private static final Map> extensionOwners = new HashMap<>(); /** Set of locale-variants JARs for this module (or null). * Added explicitly to classloader, and can be used by execution engine. */ @@ -80,12 +78,7 @@ public StandardModuleData(Manifest mf, StandardModule forModule) throws InvalidE if (classPath != null) { StringTokenizer tok = new StringTokenizer(classPath); while (tok.hasMoreTokens()) { - String ext; - try { - ext = URLDecoder.decode(tok.nextToken(), "UTF-8"); - } catch (UnsupportedEncodingException ex) { - throw new IllegalStateException(ex); - } + String ext = URLDecoder.decode(tok.nextToken(), StandardCharsets.UTF_8); File extfile; if (ext.equals("${java.home}/lib/ext/jfxrt.jar")) { // NOI18N // special handling on JDK7 @@ -158,7 +151,7 @@ public StandardModuleData(Manifest mf, StandardModule forModule) throws InvalidE } } - public StandardModuleData(ObjectInput dis) throws IOException { + public StandardModuleData(DataInput dis) throws IOException { super(dis); localeVariants = readFiles(dis); localeExtensions = readFiles(dis); @@ -166,7 +159,7 @@ public StandardModuleData(ObjectInput dis) throws IOException { } @Override - void write(ObjectOutput dos) throws IOException { + void write(DataOutput dos) throws IOException { super.write(dos); writeFiles(dos, localeVariants); writeFiles(dos, localeExtensions); @@ -175,7 +168,7 @@ void write(ObjectOutput dos) throws IOException { private static Set readFiles(DataInput is) throws IOException { int size = is.readInt(); - Set set = new HashSet(); + Set set = new HashSet<>((int) Math.ceil(size / 0.75)); while (size-- > 0) { set.add(new File(Stamps.readRelativePath(is))); } diff --git a/platform/openide.modules/src/org/openide/modules/Dependency.java b/platform/openide.modules/src/org/openide/modules/Dependency.java index f30b589bea03..e4c59a7b6d80 100644 --- a/platform/openide.modules/src/org/openide/modules/Dependency.java +++ b/platform/openide.modules/src/org/openide/modules/Dependency.java @@ -19,15 +19,18 @@ package org.openide.modules; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Pattern; -import org.openide.util.BaseUtilities; /** A dependency a module can have. Since version 7.10 this class is * {@link Serializable}. @@ -115,6 +118,7 @@ public final class Dependency implements Serializable { /** Implementation version of the Java VM. */ public static final String VM_IMPL = System.getProperty("java.vm.version"); // NOI18N + private final int type; private final int comparison; private final String name; @@ -361,6 +365,39 @@ public static Set create(int type, String body) throws IllegalArgume return deps; } + /** + * Reads a dependency from the stream. + * + * Custom persistence for faster serialization. + * @see #write(java.io.DataOutput) + */ + public static Dependency read(DataInput is) throws IOException { + int type = is.readByte(); + int comp = is.readByte(); + String name = is.readUTF(); + if (name == null || name.isBlank()) { + throw new IOException("name expected"); + } + String version = is.readUTF(); + if (version.isBlank()) { + version = null; + } + return new Dependency(type, name, comp, version); + } + + /** + * Writes a dependency to the stream. + * + * Custom persistence for faster serialization. + * @see #read(java.io.DataInput) + */ + public void write(DataOutput os) throws IOException { + os.writeByte(getType()); + os.writeByte(getComparison()); + os.writeUTF(getName()); + os.writeUTF(getVersion() != null ? getVersion() : ""); + } + /** Get the type. */ public final int getType() { return type; @@ -390,8 +427,7 @@ public boolean equals(Object o) { Dependency d = (Dependency) o; - return (type == d.type) && (comparison == d.comparison) && name.equals(d.name) && - BaseUtilities.compareObjects(version, d.version); + return (type == d.type) && (comparison == d.comparison) && name.equals(d.name) && Objects.equals(version, d.version); } /** Overridden to hash by contents. */ @@ -522,15 +558,18 @@ public DependencyKey(Dependency d) { //System.err.println("Key for " + d + " is " + this); } + @Override public int hashCode() { return name.hashCode(); } + @Override public boolean equals(Object o) { return (o instanceof DependencyKey) && ((DependencyKey) o).name.equals(name) && (((DependencyKey) o).type == type); } + @Override public String toString() { return "DependencyKey[" + name + "," + type + "]"; // NOI18N }