libbluray | branch: master | npzacs <[email protected]> | 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; } /* _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
