[libbluray-devel] Allow changes to boot class path at run time
npzacs
git at videolan.org
Sat Sep 16 13:24:14 CEST 2017
libbluray | branch: master | npzacs <npzacs at anonymous.org> | Fri Sep 15 12:59:01 2017 +0300| [676adbd9fb43ee8002858fc578068cfb0fa6d3cc] | committer: npzacs
Allow changes to boot class path at run time
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=676adbd9fb43ee8002858fc578068cfb0fa6d3cc
---
.../bdj/java/org/videolan/BDJClassLoader.java | 48 +++++++++++++++++++++-
.../java/org/videolan/BDJClassLoaderAdapter.java | 41 ++++++++++++++++++
src/libbluray/bdj/java/org/videolan/Libbluray.java | 33 +++++++++++++++
3 files changed, 121 insertions(+), 1 deletion(-)
diff --git a/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java b/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java
index d2645d16..988877e4 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java
@@ -29,6 +29,7 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.Map;
import javax.tv.xlet.Xlet;
@@ -107,6 +108,13 @@ public class BDJClassLoader extends URLClassLoader {
private BDJClassLoader(URL[] urls, String xletClass) {
super(urls);
this.xletClass = xletClass;
+
+ BDJClassLoaderAdapter a = Libbluray.getLoaderAdapter();
+ if (a != null) {
+ hideClasses = a.getHideClasses();
+ bootClasses = a.getBootClasses();
+ xletClasses = a.getXletClasses();
+ }
}
protected Xlet loadXlet() throws ClassNotFoundException,
@@ -133,7 +141,15 @@ public class BDJClassLoader extends URLClassLoader {
this.xletClass = xletClass;
}
- public Class loadClass(String name) throws java.lang.ClassNotFoundException {
+ public Class loadClass(String name) throws ClassNotFoundException {
+
+ if (hideClasses != null) {
+ if (hideClasses.get(name) != null) {
+ logger.error("Hiding class " + name);
+ throw new ClassNotFoundException(name);
+ }
+ }
+
/* hook FileSystem in java.io.File */
if (name.equals("java.io.File")) {
Class c = super.loadClass(name);
@@ -143,10 +159,21 @@ public class BDJClassLoader extends URLClassLoader {
return c;
}
+ Class bootclass = tryLoad(name, bootClasses);
+ if (bootclass != null) {
+ return bootclass;
+ }
+
try {
return super.loadClass(name);
} catch (ClassNotFoundException e0) {
logger.error("ClassNotFoundException: " + name);
+
+ Class xletclass = tryLoad(name, xletClasses);
+ if (xletclass != null) {
+ return xletclass;
+ }
+
throw e0;
} catch (Error err) {
logger.error("FATAL: " + err);
@@ -154,6 +181,21 @@ public class BDJClassLoader extends URLClassLoader {
}
}
+ private Class tryLoad(String name, Map classes) {
+ if (classes != null) {
+ try {
+ byte[] code = (byte[])classes.get(name);
+ if (code != null) {
+ logger.info("Overriding class " + name);
+ return defineClass(code, 0, code.length);
+ }
+ } catch (Exception e) {
+ logger.error("tryLoad(" + name + ") failed: " + e);
+ }
+ }
+ return null;
+ }
+
private byte[] loadClassCode(String name) throws ClassNotFoundException {
String path = name.replace('.', '/').concat(".class");
@@ -256,5 +298,9 @@ public class BDJClassLoader extends URLClassLoader {
private String xletClass;
+ private Map hideClasses; /* classes that should be hidden from Xlet */
+ private Map bootClasses; /* additional bootstrap clases */
+ private Map xletClasses; /* fallback for possibly missing classes */
+
private static final Logger logger = Logger.getLogger(BDJClassLoader.class.getName());
}
diff --git a/src/libbluray/bdj/java/org/videolan/BDJClassLoaderAdapter.java b/src/libbluray/bdj/java/org/videolan/BDJClassLoaderAdapter.java
new file mode 100644
index 00000000..cac04fec
--- /dev/null
+++ b/src/libbluray/bdj/java/org/videolan/BDJClassLoaderAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2017 VideoLAN
+ *
+ * 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 org.videolan;
+
+import java.util.Map;
+
+public interface BDJClassLoaderAdapter {
+
+ /*
+ * Modify Xlet class path at run time
+ */
+
+ /* classes that should be hidden from Xlet.
+ * Can be used to hide profile 5 or 6 classes when
+ * running as profile 2 player.
+ */
+ public abstract Map getHideClasses();
+
+ /* Additional bootstrap classes (highest priority) */
+ public abstract Map getBootClasses();
+
+ /* normal classes (lowest priority) */
+ public abstract Map getXletClasses();
+}
diff --git a/src/libbluray/bdj/java/org/videolan/Libbluray.java b/src/libbluray/bdj/java/org/videolan/Libbluray.java
index c115deef..0f7d2aeb 100644
--- a/src/libbluray/bdj/java/org/videolan/Libbluray.java
+++ b/src/libbluray/bdj/java/org/videolan/Libbluray.java
@@ -68,6 +68,35 @@ public class Libbluray {
System.setProperties(p);
}
+ /*
+ * Loader hooks
+ */
+
+ private static BDJClassLoaderAdapter loaderAdapter = null;
+
+ protected static BDJClassLoaderAdapter getLoaderAdapter() {
+ return loaderAdapter;
+ }
+
+ private static void loadAdapter(String pkg) {
+ if (pkg == null)
+ return;
+ try {
+ final Object obj = Class.forName("org.videolan." + pkg + ".Adapter").newInstance();
+ if (obj instanceof BDJClassLoaderAdapter) {
+ loaderAdapter = (BDJClassLoaderAdapter)obj;
+ } else {
+ System.err.println("Unsupported interface in " + obj);
+ }
+ } catch (Exception e) {
+ System.err.println("" + e);
+ }
+ }
+
+ /*
+ *
+ */
+
private static boolean initOnce = false;
private static void initOnce() {
if (initOnce) {
@@ -289,6 +318,9 @@ public class Libbluray {
System.err.println("System.setSecurityManager() failed: " + ex);
throw new SecurityException("Failed initializing SecurityManager");
}
+
+ loadAdapter(System.getProperty("org.videolan.loader.adapter"));
+ loadAdapter(pkg);
}
/* called only from native code */
@@ -329,6 +361,7 @@ public class Libbluray {
synchronized (bdjoFilesLock) {
bdjoFiles = null;
}
+ loaderAdapter = null;
}
/*
More information about the libbluray-devel
mailing list