Mercurial > octave
changeset 27875:1ebfa73565fe
javaaddpath: prepend dirs by default, accept "-end" arg (bug #57487)
* javaaddpath.m: Accept new "-end" argument. If prepending, iterate
over directory arguments in reverse order.
* NEWS: Note change.
* ClassHelper.java (ClassHelper.addClassPath): New argument, append.
Also allow elements to be prepended to the existing dynamic
classpath.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 27 Dec 2019 10:18:06 -0500 |
parents | 07efc76a47a9 |
children | 76373f5113db |
files | NEWS scripts/java/javaaddpath.m scripts/java/org/octave/ClassHelper.java |
diffstat | 3 files changed, 58 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Wed Dec 18 07:53:45 2019 -0500 +++ b/NEWS Fri Dec 27 10:18:06 2019 -0500 @@ -152,6 +152,8 @@ "Superclasslist" for Matlab compatibility. The original name will exist as an alias until Octave version 8.1. +- The function `javaaddpath` now prepends new directories to the existing dynamic classpath by default. To append them instead, use the new `"-end"` argument. + - An undocumented function `gui_mainfcn` has been added, for compatibility with figures created with Matlab's Guide.
--- a/scripts/java/javaaddpath.m Wed Dec 18 07:53:45 2019 -0500 +++ b/scripts/java/javaaddpath.m Fri Dec 27 10:18:06 2019 -0500 @@ -20,11 +20,16 @@ ## -*- texinfo -*- ## @deftypefn {} {} javaaddpath (@var{clspath}) ## @deftypefnx {} {} javaaddpath (@var{clspath1}, @dots{}) +## @deftypefnx {} {} javaaddpath (@dots{}, "-end") ## Add @var{clspath} to the dynamic class path of the Java virtual machine. ## ## @var{clspath} may either be a directory where @file{.class} files are ## found, or a @file{.jar} file containing Java classes. Multiple paths may ## be added at once by specifying additional arguments. +## +## If the final argument is @code{"-end"}, append the new element to the +## end of the current classpath. Otherwise, new elements are added at +## the beginning of the path. ## @seealso{javarmpath, javaclasspath} ## @end deftypefn @@ -34,12 +39,28 @@ print_usage (); endif - for i = 1:numel (varargin) + if (! iscellstr (varargin)) + error ("javaaddpath: arguments must all be character strings"); + endif + + if (strcmp (varargin{end}, "-end")) + at_end = true; + nel = nargin - 1; + rng = 1:nel; + else + ## Note that when prepending, we iterate over the arguments in + ## reverse so that a call like + ## + ## javaaddpath ("/foo", "/bar") + ## + ## results in "/foo" first in the path followed by "/bar". + nel = nargin; + at_end = false; + rng = nel:-1:1; + endif + + for i = rng clspath = varargin{i}; - if (! ischar (clspath)) - error ("javaaddpath: CLSPATH must be a string"); - endif - new_path = canonicalize_file_name (tilde_expand (clspath)); if (isfolder (new_path)) if (new_path(end) != filesep ()) @@ -49,7 +70,8 @@ error ("javaaddpath: CLSPATH does not exist: %s", clspath); endif - success = javaMethod ("addClassPath", "org.octave.ClassHelper", new_path); + success = javaMethod ("addClassPath", "org.octave.ClassHelper", + new_path, at_end); if (! success) warning ("javaaddpath: failed to add '%s' to Java classpath", new_path);
--- a/scripts/java/org/octave/ClassHelper.java Wed Dec 18 07:53:45 2019 -0500 +++ b/scripts/java/org/octave/ClassHelper.java Fri Dec 27 10:18:06 2019 -0500 @@ -38,20 +38,45 @@ /** * Add the given path to the classpath. - * @param name String - path to addd to the classpath + * @param name String - path to add to the classpath + * @param append boolean - if true, append path to classpath, otherwise prepend it. * @return boolean - true if the given path exists and was added to the classpath. * @throws Exception if an error occurs */ - public static boolean addClassPath (String name) + public static boolean addClassPath (String name, boolean append) throws Exception { boolean found = false; java.io.File f = new java.io.File (name); if (f.exists ()) { - loader.addClassPath (name); found = true; + + if (append) + { + loader.addClassPath (name); + } + else + { + // create a completely new class loader because java.net.URLClassLoader appears to have no method to prepend directories to the existing classpath + + // FIXME: is there a more efficient way to do this job? + + java.net.URL[] urls = loader.getURLs (); + + ClassLoader l = ClassHelper.class.getClassLoader (); + loader = (l instanceof OctClassLoader ? (OctClassLoader) l : + new OctClassLoader (l)); + + loader.addClassPath (name); + + for (int i = 0; i < urls.length; i++) + { + loader.addURL (urls[i]); + } + } } + return (found); }