[libbluray-devel] [Git][videolan/libbluray][master] 3 commits: Cosmetics

Petri Hintukainen gitlab at videolan.org
Wed Apr 17 09:18:23 CEST 2019



Petri Hintukainen pushed to branch master at VideoLAN / libbluray


Commits:
f43a2a8d by hpi1 at 2019-04-15T06:07:50Z
Cosmetics

- - - - -
487fc80c by hpi1 at 2019-04-16T09:03:31Z
BDFileSystem: enable hooks after JVM has been booted

- - - - -
a1869cb4 by hpi1 at 2019-04-16T09:54:08Z
Java 8+: Unconditionally hook java.io.FileSystem class

This is done during JVM boot stage
=> unsupported FileSystem implementation will prevent JVM boot.

Fixes skipping wrapper class sometimes when java.io.File.fs is static final.

- - - - -


3 changed files:

- src/libbluray/bdj/java/java/io/BDFileSystem.java
- + src/libbluray/bdj/java/java/io/DefaultFileSystem.java
- src/libbluray/bdj/java/org/videolan/Libbluray.java


Changes:

=====================================
src/libbluray/bdj/java/java/io/BDFileSystem.java
=====================================
@@ -19,6 +19,7 @@
 /*
  * Wrapper for java.io.FileSystem class.
  *
+ * - resolve relative files to Xlet home directory.
  * - replace getBooleanAttributes() for relative paths.
  *   Pretend files exist, if those are in xlet home directory (inside .jar).
  *   No other relative paths are allowed.
@@ -40,30 +41,50 @@ import org.videolan.Logger;
 
 public abstract class BDFileSystem extends FileSystem {
 
-    private static final Logger logger = Logger.getLogger(BDFileSystem.class.getName());
-
-    protected final FileSystem fs;
+    /*
+     * Access to native filesystem
+     *
+     * (for org.videolan.VFSCache, org.videolan.CacheDir)
+     */
 
     private static FileSystem nativeFileSystem;
 
     static {
-        /* Java 8: getFileSystem() no longer exists on java.io.FileSystem */
         try {
-            nativeFileSystem = (FileSystem)Class.forName("java.io.DefaultFileSystem")
-                .getDeclaredMethod("getFileSystem", new Class[0])
+            /* Java < 8 */
+            nativeFileSystem = (FileSystem)FileSystem.class
+                .getDeclaredMethod("getFileSystem",new Class[0])
                 .invoke(null, new Object[0]);
         } catch (Exception e) {
             try {
-                nativeFileSystem = (FileSystem)FileSystem.class
-                    .getDeclaredMethod("getFileSystem",new Class[0])
-                    .invoke(null, new Object[0]);
-            } catch (Exception t) {
-                System.err.print("Couldn't find native filesystem: " + t);
+                /* Just use our wrapper.  If it fails, JVM won't be booted anyway ... */
+                nativeFileSystem = DefaultFileSystem.getNativeFileSystem();
+            } catch (Throwable t) {
+                System.err.print("Couldn't find native filesystem: " + e);
             }
         }
     }
 
+    /* org.videolan.CacheDir uses this function to clean up cache directory */
+    public static String[] nativeList(File f) {
+        return nativeFileSystem.list(f);
+    }
+
+    /* org.videolan.VFSCache uses this function to check if file has been cached */
+    public static boolean nativeFileExists(String path) {
+        return nativeFileSystem.getBooleanAttributes(new File(path)) != 0;
+    }
+
+    /*
+     * Replace File.fs for Xlets (required with Java < 8 where this is not done unconditionally)
+     *
+     * (called by org.videolan.BDJClassLoader)
+     */
+
     public static void init(final Class c) {
+
+        setBooted();
+
         AccessController.doPrivileged(
             new PrivilegedAction() {
                 public Object run() {
@@ -79,33 +100,49 @@ public abstract class BDFileSystem extends FileSystem {
             filesystem = c.getDeclaredField("fs");
             filesystem.setAccessible(true);
 
-            /* Java 8: remove "final" modifier from the field */
-            Field modifiersField = Field.class.getDeclaredField("modifiers");
-            modifiersField.setAccessible(true);
-            modifiersField.setInt(filesystem, filesystem.getModifiers() & ~Modifier.FINAL);
-
             FileSystem fs = (FileSystem)filesystem.get(null);
             if (fs instanceof BDFileSystemImpl) {
                 //System.err.print("FileSystem already wrapped");
             } else {
+                /* Java 8: we should never end up here ... */
+                /* Java 8: remove "final" modifier from the field */
+                //Field modifiersField = Field.class.getDeclaredField("modifiers");
+                //modifiersField.setAccessible(true);
+                //modifiersField.setInt(filesystem, filesystem.getModifiers() & ~Modifier.FINAL);
                 filesystem.set(null, new BDFileSystemImpl(fs));
             }
         } catch (Exception t) {
-            System.err.print("Hooking FileSystem class failed: " + t);
+            error("Hooking FileSystem class failed: " + t);
         }
     }
 
-    public static String[] nativeList(File f) {
-        return nativeFileSystem.list(f);
+    /*
+     * enable after JVM boot is completed
+     */
+
+    private static Logger logger = null;
+    private static boolean booted = false;
+
+    /* Called by org.videolan.Libbluray.initOnce() */
+    public static void setBooted() {
+        if (!booted) {
+            booted = true;
+            logger = Logger.getLogger(BDFileSystem.class.getName());
+        }
     }
 
-    public static boolean nativeFileExists(String path) {
-        return nativeFileSystem.getBooleanAttributes(new File(path)) != 0;
+    private static void error(String msg) {
+        if (logger != null) {
+            logger.error(msg);
+        }
     }
 
     /*
+     *
      */
 
+    protected final FileSystem fs;
+
     public BDFileSystem(FileSystem fs) {
         this.fs = fs;
     }
@@ -139,6 +176,9 @@ public abstract class BDFileSystem extends FileSystem {
     }
 
     public String resolve(String parent, String child) {
+        if (!booted)
+            return fs.resolve(parent, child);
+
         if (parent == null || parent.equals("") || parent.equals(".")) {
             parent = getHomeDir();
         }
@@ -168,6 +208,9 @@ public abstract class BDFileSystem extends FileSystem {
     }
 
     public String resolve(File f) {
+        if (!booted)
+            return fs.resolve(f);
+
         if (!f.isAbsolute()) {
             logger.info("resolve relative file " + f.getPath());
             return resolve(BDJXletContext.getCurrentXletHome(), f.getPath());
@@ -182,6 +225,9 @@ public abstract class BDFileSystem extends FileSystem {
     }
 
     public String canonicalize(String path) throws IOException {
+        if (!booted)
+            return fs.canonicalize(path);
+
         String canonPath = fs.canonicalize(path);
         String cachePath = BDJLoader.getCachedFile(canonPath);
         if (cachePath != canonPath) {
@@ -191,6 +237,9 @@ public abstract class BDFileSystem extends FileSystem {
     }
 
     public int getBooleanAttributes(File f) {
+        if (!booted)
+            return fs.getBooleanAttributes(f);
+
         if (f.isAbsolute()) {
             return fs.getBooleanAttributes(f);
         }
@@ -217,6 +266,9 @@ public abstract class BDFileSystem extends FileSystem {
     }
 
     public long getLength(File f) {
+        if (!booted)
+            return fs.getLength(f);
+
         if (f.isAbsolute()) {
             return fs.getLength(f);
         }
@@ -263,7 +315,7 @@ public abstract class BDFileSystem extends FileSystem {
                 args = new Object[] {(Object)path, (Object)new Boolean(restrictive)};
             }
         } catch (NoSuchMethodException e) {
-            logger.error("no matching FileSystem.createFileExclusively found !");
+            error("no matching FileSystem.createFileExclusively found !");
             throw new IOException();
         }
 
@@ -272,14 +324,14 @@ public abstract class BDFileSystem extends FileSystem {
             Boolean result = (Boolean)m.invoke(fs, args);
             return result.booleanValue();
         } catch (IllegalAccessException e) {
-            logger.error("" + e);
+            error("" + e);
             throw new IOException();
         } catch (InvocationTargetException e) {
             Throwable t = e.getTargetException();
             if (t instanceof IOException) {
                 throw (IOException)t;
             }
-            logger.error("" + t);
+            error("" + t);
             throw new IOException();
         }
     }
@@ -299,6 +351,8 @@ public abstract class BDFileSystem extends FileSystem {
     }
 
     public String[] list(File f) {
+        if (!booted)
+            return fs.list(f);
 
         String path = f.getPath();
         String root = System.getProperty("bluray.vfs.root");


=====================================
src/libbluray/bdj/java/java/io/DefaultFileSystem.java
=====================================
@@ -0,0 +1,51 @@
+/*
+ * This file is part of libbluray
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package java.io;
+
+class DefaultFileSystem {
+
+    static FileSystem getNativeFileSystem() {
+        Exception e1, e2, e3;
+        try {
+            return (FileSystem)Class.forName(System.getProperty("org.videolan.bdj_filesystem")).newInstance();
+        } catch (Exception e) {
+            e3 = e;
+        }
+        try {
+            return (FileSystem)Class.forName("java.io.UnixFileSystem").newInstance();
+        } catch (Exception e) {
+            e1 = e;
+        }
+        try {
+            return (FileSystem)Class.forName("java.io.WinNTFileSystem").newInstance();
+        } catch (Exception e) {
+            e2 = e;
+        }
+
+        /* No way to recover from here */
+        System.err.println("Unsupported native filesystem !\n\t" + e1 + "\n\t" + e2 + "\n\t" + e3);
+        //Runtime.getRuntime().halt(-1);
+        throw new Error("No filesystem implementation found");
+    }
+
+    public static FileSystem getFileSystem() {
+        FileSystem nativeFs = getNativeFileSystem();
+        return new BDFileSystemImpl(nativeFs);
+    }
+}


=====================================
src/libbluray/bdj/java/org/videolan/Libbluray.java
=====================================
@@ -138,6 +138,9 @@ public class Libbluray {
         } catch (Throwable t) {
             System.err.println("Hooking socket factory failed: " + t + "\n" + Logger.dumpStack(t));
         }
+
+        /* enable filesystem hooks */
+        java.io.BDFileSystem.setBooted();
     }
 
     private static String canonicalize(String path, boolean create) {



View it on GitLab: https://code.videolan.org/videolan/libbluray/compare/6c0e42b88ee167e052944757b57537a72b3ddcda...a1869cb4a18b12f4c5a1bb6b69f8b0da24c28f73

-- 
View it on GitLab: https://code.videolan.org/videolan/libbluray/compare/6c0e42b88ee167e052944757b57537a72b3ddcda...a1869cb4a18b12f4c5a1bb6b69f8b0da24c28f73
You're receiving this email because of your account on code.videolan.org.



More information about the libbluray-devel mailing list