src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
Print this page
@@ -151,27 +151,39 @@
private static final int MINOR_VERSION = 1;
private static final int DEFLATED = 1 << 0;
private File parent;
+ // location of native libs for this library (may be outside the library)
+ // null:default, to use a per-module 'lib' directory
+ private File natlibs;
+ // location of native cmds for this library (may be outside the library)
+ // null:default, to use a per-module 'bin' directory
+ private File natcmds;
+
private Set<StorageOption> opts;
public File parent() { return parent; }
+ public File natlibs() { return natlibs; }
+ public File natcmds() { return natcmds; }
public boolean isDeflated() {
return opts.contains(StorageOption.DEFLATED);
}
- private Header(File root, File p, Set<StorageOption> opts) {
+ private Header(File root, File p, File natlibs, File natcmds,
+ Set<StorageOption> opts) {
super(MAJOR_VERSION, MINOR_VERSION,
FileConstants.Type.LIBRARY_HEADER,
new File(root, FILE));
this.parent = p;
+ this.natlibs = natlibs;
+ this.natcmds = natcmds;
this.opts = new HashSet<>(opts);
}
private Header(File root) {
- this(root, null, Collections.<StorageOption>emptySet());
+ this(root, null, null, null, Collections.<StorageOption>emptySet());
}
protected void storeRest(DataOutputStream out)
throws IOException
{
@@ -180,10 +192,16 @@
flags |= DEFLATED;
out.writeShort(flags);
out.writeByte((parent != null) ? 1 : 0);
if (parent != null)
out.writeUTF(parent.toString());
+ out.writeByte((natlibs != null) ? 1 : 0);
+ if (natlibs != null)
+ out.writeUTF(natlibs.toString());
+ out.writeByte((natcmds != null) ? 1 : 0);
+ if (natcmds != null)
+ out.writeUTF(natcmds.toString());
}
protected void loadRest(DataInputStream in)
throws IOException
{
@@ -192,10 +210,16 @@
if ((flags & DEFLATED) == DEFLATED)
opts.add(StorageOption.DEFLATED);
int b = in.readByte();
if (b != 0)
parent = new File(in.readUTF());
+ b = in.readByte();
+ if (b != 0)
+ natlibs = new File(in.readUTF());
+ b = in.readByte();
+ if (b != 0)
+ natcmds = new File(in.readUTF());
}
private static Header load(File f)
throws IOException
{
@@ -206,19 +230,23 @@
}
private final File root;
private final File canonicalRoot;
- private File parentPath = null;
- private SimpleLibrary parent = null;
+ private File parentPath;
+ private File natlibs;
+ private File natcmds;
+ private SimpleLibrary parent;
private final Header hd;
public String name() { return root.toString(); }
public File root() { return canonicalRoot; }
public int majorVersion() { return hd.majorVersion; }
public int minorVersion() { return hd.minorVersion; }
public SimpleLibrary parent() { return parent; }
+ public File natlibs() { return natlibs; }
+ public File natcmds() { return natcmds; }
public boolean isDeflated() { return hd.isDeflated(); }
private URI location = null;
public URI location() {
if (location == null)
@@ -231,60 +259,116 @@
return (this.getClass().getName()
+ "[" + canonicalRoot
+ ", v" + hd.majorVersion + "." + hd.minorVersion + "]");
}
- private SimpleLibrary(File path, boolean create, File parentPath, Set<StorageOption> opts)
+ private static void ensureDirectory(File dir) throws IOException {
+ if (!dir.isDirectory())
+ throw new IOException(dir + ": Not a directory");
+ }
+
+ private static void warnWriteable(File dir) {
+ if (!dir.canWrite())
+ // TODO: where to write the warning message???
+ System.out.println("Warning: " + dir + " is not writeable.");
+ }
+
+ private SimpleLibrary(File path, boolean create, File parentPath,
+ File natlibs, File natcmds, Set<StorageOption> opts)
throws IOException
{
root = path;
canonicalRoot = root.getCanonicalFile();
- if (root.exists()) {
- if (!root.isDirectory())
+ boolean exists = root.exists();
+ boolean directory = root.isDirectory();
+ if (!create) {
+ if (!exists)
+ throw new FileNotFoundException(root.toString());
+ if (!directory)
throw new IOException(root + ": Exists but is not a directory");
hd = Header.load(root);
if (hd.parent() != null) {
parent = open(hd.parent());
- parentPath = hd.parent();
+ this.parentPath = hd.parent();
}
+ if (hd.natlibs() != null)
+ this.natlibs = hd.natlibs();
+ if (hd.natcmds() != null)
+ this.natcmds = hd.natcmds();
return;
}
- if (!create)
- throw new FileNotFoundException(root.toString());
+ // create
+ if (exists) {
+ if (!directory)
+ throw new IOException(root + ": Not a directory");
+ else if (root.list().length != 0)
+ throw new IOException(root + ": Already Exists");
+ } else if (!root.mkdirs())
+ throw new IOException(root + ": Cannot create library directory");
if (parentPath != null) {
this.parent = open(parentPath);
this.parentPath = this.parent.root();
}
- if (!root.mkdirs())
- throw new IOException(root + ": Cannot create library directory");
- hd = new Header(canonicalRoot, this.parentPath, opts);
+ if (natlibs != null) {
+ // resolve against the working dir, and store the absolute path
+ this.natlibs = natlibs.getCanonicalFile();
+ if (!this.natlibs.exists()) {
+ if (!this.natlibs.mkdir())
+ throw new IOException(this.natlibs + ": Cannot create lib directory");
+ } else {
+ ensureDirectory(this.natlibs);
+ warnWriteable(this.natlibs);
+ }
+ }
+ if (natcmds != null) {
+ this.natcmds = natcmds.getCanonicalFile();
+ if (!this.natcmds.exists()) {
+ if (!this.natcmds.mkdir())
+ throw new IOException(this.natcmds + ": Cannot create cmd directory");
+ } else {
+ ensureDirectory(this.natcmds);
+ warnWriteable(this.natcmds);
+ }
+ }
+ hd = new Header(canonicalRoot, this.parentPath, this.natlibs,
+ this.natcmds, opts);
hd.store();
}
- public static SimpleLibrary create(File path, File parent, Set<StorageOption> opts)
+ public static SimpleLibrary create(File path, File parent, File natlibs,
+ File natcmds, Set<StorageOption> opts)
throws IOException
{
- return new SimpleLibrary(path, true, parent, opts);
+ return new SimpleLibrary(path, true, parent, natlibs, natcmds, opts);
}
+ public static SimpleLibrary create(File path, File parent,
+ Set<StorageOption> opts)
+ throws IOException
+ {
+ return new SimpleLibrary(path, true, parent, null, null, opts);
+ }
+
public static SimpleLibrary create(File path, File parent)
throws IOException
{
- return new SimpleLibrary(path, true, parent, Collections.<StorageOption>emptySet());
+ return new SimpleLibrary(path, true, parent, null, null,
+ Collections.<StorageOption>emptySet());
}
public static SimpleLibrary create(File path, Set<StorageOption> opts)
throws IOException
{
// ## Should default parent to $JAVA_HOME/lib/modules
- return new SimpleLibrary(path, true, null, opts);
+ return new SimpleLibrary(path, true, null, null, null, opts);
}
public static SimpleLibrary open(File path)
throws IOException
{
- return new SimpleLibrary(path, false, null, Collections.<StorageOption>emptySet());
+ return new SimpleLibrary(path, false, null, null, null,
+ Collections.<StorageOption>emptySet());
}
private static final JigsawModuleSystem jms
= JigsawModuleSystem.instance();
@@ -967,11 +1051,11 @@
throws ConfigurationException, IOException, SignatureException
{
BufferedInputStream bin = new BufferedInputStream(is);
DataInputStream in = new DataInputStream(bin);
File md = null;
- try (ModuleFile.Reader mr = new ModuleFile.Reader(in)) {
+ try (ModuleFile.Reader mr = new ModuleFile.Reader(in, this)) {
byte[] mib = mr.readStart();
ModuleInfo mi = jms.parseModuleInfo(mib);
md = moduleDir(mi.id());
ModuleId mid = mi.id();
if (md.exists())
@@ -1010,11 +1094,11 @@
return mid;
} catch (IOException | SignatureException x) {
if (md != null && md.exists()) {
try {
- Files.deleteTree(md);
+ ModuleFile.Reader.remove(md);
} catch (IOException y) {
y.initCause(x);
throw y;
}
}
@@ -1184,10 +1268,11 @@
{
ModuleId mid;
if (mf.getName().endsWith(".jar"))
mid = installFromJarFile(mf, verifySignature, strip);
else {
+ // ## Assume jmod file, should we check extension?
try (FileInputStream in = new FileInputStream(mf)) {
mid = install(in, verifySignature, strip);
}
}
return mid;
@@ -1336,14 +1421,18 @@
}
public File findLocalNativeLibrary(ModuleId mid, String name)
throws IOException
{
- File md = findModuleDir(mid);
- if (md == null)
+ File f = natlibs();
+ if (f == null) {
+ f = findModuleDir(mid);
+ if (f == null)
return null;
- File f = new File(new File(md, "lib"), name);
+ f = new File(f, "lib");
+ }
+ f = new File(f, name);
if (!f.exists())
return null;
return f;
}