summaryrefslogtreecommitdiffstats
path: root/libjava
diff options
context:
space:
mode:
authorgary <gary@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-15 10:25:38 +0000
committergary <gary@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-15 10:25:38 +0000
commit1b6d342ee8adef6fef52f76be20dc6e4d39f6938 (patch)
tree4fd1e5d43e9e9e5d5e92941734f010014917598e /libjava
parentac8d4d796aa34fbea4dfb1505840689faba5ec1f (diff)
downloadppe42-gcc-1b6d342ee8adef6fef52f76be20dc6e4d39f6938.tar.gz
ppe42-gcc-1b6d342ee8adef6fef52f76be20dc6e4d39f6938.zip
2007-01-15 Gary Benson <gbenson@redhat.com>
* java/net/URLClassLoader.java: Removed. * gnu/java/net/loader/Load_gcjlib.java: New file. * gnu/gcj/runtime/BootClassLoader.java: Ensure core URL handler is present in static executables. * sources.am, Makefile.in: Rebuilt. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120791 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog8
-rw-r--r--libjava/Makefile.in3
-rw-r--r--libjava/classpath/lib/gnu/gcj/runtime/BootClassLoader.classbin1561 -> 1706 bytes
-rw-r--r--libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib$SoResource.classbin0 -> 1102 bytes
-rw-r--r--libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib.classbin0 -> 1645 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$1.classbin1022 -> 1022 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$2.classbin908 -> 908 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$CoreResource.classbin1826 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$CoreURLLoader.classbin1344 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$FileResource.classbin1739 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$FileURLLoader.classbin1278 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$JarURLLoader.classbin3418 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$JarURLResource.classbin2202 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$RemoteResource.classbin1152 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$RemoteURLLoader.classbin1724 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$Resource.classbin1217 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$SoResource.classbin1097 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$SoURLLoader.classbin1625 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader$URLLoader.classbin1354 -> 0 bytes
-rw-r--r--libjava/classpath/lib/java/net/URLClassLoader.classbin14234 -> 14476 bytes
-rw-r--r--libjava/gnu/gcj/runtime/BootClassLoader.h3
-rw-r--r--libjava/gnu/gcj/runtime/BootClassLoader.java8
-rw-r--r--libjava/gnu/java/net/loader/Load_gcjlib$SoResource.h50
-rw-r--r--libjava/gnu/java/net/loader/Load_gcjlib.h58
-rw-r--r--libjava/gnu/java/net/loader/Load_gcjlib.java77
-rw-r--r--libjava/java/net/URLClassLoader.h25
-rw-r--r--libjava/java/net/URLClassLoader.java1448
-rw-r--r--libjava/sources.am3
28 files changed, 224 insertions, 1459 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index af4a1a7cfba..ad6c1fba4ef 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,11 @@
+2007-01-15 Gary Benson <gbenson@redhat.com>
+
+ * java/net/URLClassLoader.java: Removed.
+ * gnu/java/net/loader/Load_gcjlib.java: New file.
+ * gnu/gcj/runtime/BootClassLoader.java: Ensure core
+ URL handler is present in static executables.
+ * sources.am, Makefile.in: Rebuilt.
+
2007-01-14 H.J. Lu <hongjiu.lu@intel.com>
* Makefile.am (libgcj_la_LDFLAGS): Add
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index 0f052e67b9d..e03542934f2 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -1922,6 +1922,7 @@ classpath/gnu/java/net/loader/FileResource.java \
classpath/gnu/java/net/loader/FileURLLoader.java \
classpath/gnu/java/net/loader/JarURLLoader.java \
classpath/gnu/java/net/loader/JarURLResource.java \
+gnu/java/net/loader/Load_gcjlib.java \
classpath/gnu/java/net/loader/RemoteResource.java \
classpath/gnu/java/net/loader/RemoteURLLoader.java \
classpath/gnu/java/net/loader/Resource.java \
@@ -4402,7 +4403,7 @@ classpath/java/net/SocketTimeoutException.java \
classpath/java/net/URI.java \
classpath/java/net/URISyntaxException.java \
classpath/java/net/URL.java \
-java/net/URLClassLoader.java \
+classpath/java/net/URLClassLoader.java \
classpath/java/net/URLConnection.java \
classpath/java/net/URLDecoder.java \
classpath/java/net/URLEncoder.java \
diff --git a/libjava/classpath/lib/gnu/gcj/runtime/BootClassLoader.class b/libjava/classpath/lib/gnu/gcj/runtime/BootClassLoader.class
index 1635a304040..857b7a17cba 100644
--- a/libjava/classpath/lib/gnu/gcj/runtime/BootClassLoader.class
+++ b/libjava/classpath/lib/gnu/gcj/runtime/BootClassLoader.class
Binary files differ
diff --git a/libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib$SoResource.class b/libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib$SoResource.class
new file mode 100644
index 00000000000..86c42ea8020
--- /dev/null
+++ b/libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib$SoResource.class
Binary files differ
diff --git a/libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib.class b/libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib.class
new file mode 100644
index 00000000000..3293b2e59e7
--- /dev/null
+++ b/libjava/classpath/lib/gnu/java/net/loader/Load_gcjlib.class
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$1.class b/libjava/classpath/lib/java/net/URLClassLoader$1.class
index 4481e7b35d5..762625a3c7a 100644
--- a/libjava/classpath/lib/java/net/URLClassLoader$1.class
+++ b/libjava/classpath/lib/java/net/URLClassLoader$1.class
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$2.class b/libjava/classpath/lib/java/net/URLClassLoader$2.class
index 64c9e24573b..741aa3bf03f 100644
--- a/libjava/classpath/lib/java/net/URLClassLoader$2.class
+++ b/libjava/classpath/lib/java/net/URLClassLoader$2.class
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$CoreResource.class b/libjava/classpath/lib/java/net/URLClassLoader$CoreResource.class
deleted file mode 100644
index f3729420381..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$CoreResource.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$CoreURLLoader.class b/libjava/classpath/lib/java/net/URLClassLoader$CoreURLLoader.class
deleted file mode 100644
index 050f529734c..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$CoreURLLoader.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$FileResource.class b/libjava/classpath/lib/java/net/URLClassLoader$FileResource.class
deleted file mode 100644
index e7a12687ef3..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$FileResource.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$FileURLLoader.class b/libjava/classpath/lib/java/net/URLClassLoader$FileURLLoader.class
deleted file mode 100644
index d750821a99e..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$FileURLLoader.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$JarURLLoader.class b/libjava/classpath/lib/java/net/URLClassLoader$JarURLLoader.class
deleted file mode 100644
index 11c1e9dc61a..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$JarURLLoader.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$JarURLResource.class b/libjava/classpath/lib/java/net/URLClassLoader$JarURLResource.class
deleted file mode 100644
index 74ebc398101..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$JarURLResource.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$RemoteResource.class b/libjava/classpath/lib/java/net/URLClassLoader$RemoteResource.class
deleted file mode 100644
index 19b703190ee..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$RemoteResource.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$RemoteURLLoader.class b/libjava/classpath/lib/java/net/URLClassLoader$RemoteURLLoader.class
deleted file mode 100644
index d32ac11656c..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$RemoteURLLoader.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$Resource.class b/libjava/classpath/lib/java/net/URLClassLoader$Resource.class
deleted file mode 100644
index bb4d13a6ba0..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$Resource.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$SoResource.class b/libjava/classpath/lib/java/net/URLClassLoader$SoResource.class
deleted file mode 100644
index 4e7417a7d63..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$SoResource.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$SoURLLoader.class b/libjava/classpath/lib/java/net/URLClassLoader$SoURLLoader.class
deleted file mode 100644
index 403dfafd09c..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$SoURLLoader.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader$URLLoader.class b/libjava/classpath/lib/java/net/URLClassLoader$URLLoader.class
deleted file mode 100644
index 8b272bdb36d..00000000000
--- a/libjava/classpath/lib/java/net/URLClassLoader$URLLoader.class
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/lib/java/net/URLClassLoader.class b/libjava/classpath/lib/java/net/URLClassLoader.class
index 118acceca43..ceb736bdc91 100644
--- a/libjava/classpath/lib/java/net/URLClassLoader.class
+++ b/libjava/classpath/lib/java/net/URLClassLoader.class
Binary files differ
diff --git a/libjava/gnu/gcj/runtime/BootClassLoader.h b/libjava/gnu/gcj/runtime/BootClassLoader.h
index dbfd1567162..df9fcdbe43b 100644
--- a/libjava/gnu/gcj/runtime/BootClassLoader.h
+++ b/libjava/gnu/gcj/runtime/BootClassLoader.h
@@ -37,6 +37,9 @@ public:
::java::lang::Class * bootLoadClass(::java::lang::String *);
::java::net::URL * bootGetResource(::java::lang::String *);
::java::util::Enumeration * bootGetResources(::java::lang::String *);
+public: // actually package-private
+ static ::java::lang::Class * coreHandler;
+public:
static ::java::lang::Class class$;
};
diff --git a/libjava/gnu/gcj/runtime/BootClassLoader.java b/libjava/gnu/gcj/runtime/BootClassLoader.java
index 84952359aab..731703ab8f3 100644
--- a/libjava/gnu/gcj/runtime/BootClassLoader.java
+++ b/libjava/gnu/gcj/runtime/BootClassLoader.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation
+/* Copyright (C) 2005, 2007 Free Software Foundation
This file is part of libgcj.
@@ -8,6 +8,7 @@ details. */
package gnu.gcj.runtime;
+import gnu.java.net.protocol.core.Handler;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
@@ -21,6 +22,11 @@ import java.util.Enumeration;
*/
public final class BootClassLoader extends HelperClassLoader
{
+ // This forces the core URL handler to be included in statically
+ // linked executables. The line that adds core:/ to the search
+ // path fails otherwise.
+ static Class coreHandler = gnu.java.net.protocol.core.Handler.class;
+
BootClassLoader(String libdir)
{
// The BootClassLoader is the top of the delegation chain. It does not
diff --git a/libjava/gnu/java/net/loader/Load_gcjlib$SoResource.h b/libjava/gnu/java/net/loader/Load_gcjlib$SoResource.h
new file mode 100644
index 00000000000..da8a2aca194
--- /dev/null
+++ b/libjava/gnu/java/net/loader/Load_gcjlib$SoResource.h
@@ -0,0 +1,50 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_java_net_loader_Load_gcjlib$SoResource__
+#define __gnu_java_net_loader_Load_gcjlib$SoResource__
+
+#pragma interface
+
+#include <gnu/java/net/loader/Resource.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace java
+ {
+ namespace net
+ {
+ namespace loader
+ {
+ class Load_gcjlib;
+ class Load_gcjlib$SoResource;
+ }
+ }
+ }
+ }
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ }
+ }
+}
+
+class gnu::java::net::loader::Load_gcjlib$SoResource : public ::gnu::java::net::loader::Resource
+{
+
+public: // actually package-private
+ Load_gcjlib$SoResource(::gnu::java::net::loader::Load_gcjlib *, ::java::net::URL *);
+public:
+ ::java::io::InputStream * getInputStream();
+ jint getLength();
+ ::java::net::URL * getURL();
+private:
+ ::java::net::URL * __attribute__((aligned(__alignof__( ::gnu::java::net::loader::Resource)))) url;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_java_net_loader_Load_gcjlib$SoResource__
diff --git a/libjava/gnu/java/net/loader/Load_gcjlib.h b/libjava/gnu/java/net/loader/Load_gcjlib.h
new file mode 100644
index 00000000000..69d2ef5ac6f
--- /dev/null
+++ b/libjava/gnu/java/net/loader/Load_gcjlib.h
@@ -0,0 +1,58 @@
+
+// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
+
+#ifndef __gnu_java_net_loader_Load_gcjlib__
+#define __gnu_java_net_loader_Load_gcjlib__
+
+#pragma interface
+
+#include <gnu/java/net/loader/URLLoader.h>
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class SharedLibHelper;
+ }
+ }
+ namespace java
+ {
+ namespace net
+ {
+ namespace loader
+ {
+ class Load_gcjlib;
+ class Resource;
+ class URLStreamHandlerCache;
+ }
+ }
+ }
+ }
+ namespace java
+ {
+ namespace net
+ {
+ class URL;
+ class URLClassLoader;
+ class URLStreamHandlerFactory;
+ }
+ }
+}
+
+class gnu::java::net::loader::Load_gcjlib : public ::gnu::java::net::loader::URLLoader
+{
+
+public:
+ Load_gcjlib(::java::net::URLClassLoader *, ::gnu::java::net::loader::URLStreamHandlerCache *, ::java::net::URLStreamHandlerFactory *, ::java::net::URL *, ::java::net::URL *);
+ ::java::lang::Class * getClass(::java::lang::String *);
+ ::gnu::java::net::loader::Resource * getResource(::java::lang::String *);
+private:
+ ::gnu::gcj::runtime::SharedLibHelper * __attribute__((aligned(__alignof__( ::gnu::java::net::loader::URLLoader)))) helper;
+public:
+ static ::java::lang::Class class$;
+};
+
+#endif // __gnu_java_net_loader_Load_gcjlib__
diff --git a/libjava/gnu/java/net/loader/Load_gcjlib.java b/libjava/gnu/java/net/loader/Load_gcjlib.java
new file mode 100644
index 00000000000..ea392041f91
--- /dev/null
+++ b/libjava/gnu/java/net/loader/Load_gcjlib.java
@@ -0,0 +1,77 @@
+/* Copyright (C) 2007 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.java.net.loader;
+
+import gnu.gcj.runtime.SharedLibHelper;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * A <code>Load_gcjlib</code> is a type of <code>URLLoader</code>
+ * that loads classes and resources from a shared library.
+ */
+public final class Load_gcjlib extends URLLoader
+{
+ private SharedLibHelper helper;
+
+ public Load_gcjlib(URLClassLoader classloader,
+ URLStreamHandlerCache cache,
+ URLStreamHandlerFactory factory,
+ URL url, URL absoluteUrl)
+ {
+ super(classloader, cache, factory, url, absoluteUrl);
+ helper = SharedLibHelper.findHelper(classloader, url.getFile(),
+ noCertCodeSource, true);
+ }
+
+ public Class getClass(String className)
+ {
+ return helper.findClass(className);
+ }
+
+ public Resource getResource(String name)
+ {
+ URL url = helper.findResource(name);
+ if (url == null)
+ return null;
+ return new SoResource(this, url);
+ }
+
+ final static class SoResource extends Resource
+ {
+ private final URL url;
+
+ SoResource(Load_gcjlib loader, URL url)
+ {
+ super(loader);
+ this.url = url;
+ }
+
+ public InputStream getInputStream() throws IOException
+ {
+ URLConnection conn = url.openConnection();
+ return conn.getInputStream();
+ }
+
+ public int getLength()
+ {
+ // FIXME we could find this by asking the core object.
+ return -1;
+ }
+
+ public URL getURL ()
+ {
+ return url;
+ }
+ }
+}
diff --git a/libjava/java/net/URLClassLoader.h b/libjava/java/net/URLClassLoader.h
index 25fe59ab785..2e5f15c9bda 100644
--- a/libjava/java/net/URLClassLoader.h
+++ b/libjava/java/net/URLClassLoader.h
@@ -11,14 +11,26 @@
extern "Java"
{
+ namespace gnu
+ {
+ namespace java
+ {
+ namespace net
+ {
+ namespace loader
+ {
+ class Resource;
+ class URLStreamHandlerCache;
+ }
+ }
+ }
+ }
namespace java
{
namespace net
{
class URL;
class URLClassLoader;
- class URLClassLoader$Resource;
- class URLStreamHandler;
class URLStreamHandlerFactory;
}
namespace security
@@ -52,12 +64,9 @@ public: // actually protected
public:
virtual ::java::lang::String * toString();
private:
- ::java::net::URLClassLoader$Resource * findURLResource(::java::lang::String *);
+ ::gnu::java::net::loader::Resource * findURLResource(::java::lang::String *);
public:
virtual ::java::net::URL * findResource(::java::lang::String *);
-public: // actually package-private
- virtual ::java::net::URLStreamHandler * getURLStreamHandler(::java::lang::String *);
-public:
virtual ::java::util::Enumeration * findResources(::java::lang::String *);
public: // actually protected
virtual ::java::security::PermissionCollection * getPermissions(::java::security::CodeSource *);
@@ -68,8 +77,8 @@ public:
public: // actually package-private
static ::java::lang::Class * access$0(::java::net::URLClassLoader *, ::java::lang::String *, JArray< jbyte > *, jint, jint, ::java::security::CodeSource *);
private:
- static ::java::util::HashMap * urlloaders;
- static ::java::util::HashMap * factoryCache;
+ static ::gnu::java::net::loader::URLStreamHandlerCache * factoryCache;
+ static ::java::lang::String * URL_LOADER_PREFIX;
::java::util::Vector * __attribute__((aligned(__alignof__( ::java::security::SecureClassLoader)))) urls;
::java::util::Vector * urlinfos;
::java::net::URLStreamHandlerFactory * factory;
diff --git a/libjava/java/net/URLClassLoader.java b/libjava/java/net/URLClassLoader.java
deleted file mode 100644
index fd70fdf2045..00000000000
--- a/libjava/java/net/URLClassLoader.java
+++ /dev/null
@@ -1,1448 +0,0 @@
-/* URLClassLoader.java -- ClassLoader that loads classes from one or more URLs
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath 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
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package java.net;
-
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FilePermission;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.CodeSource;
-import java.security.PermissionCollection;
-import java.security.PrivilegedAction;
-import java.security.SecureClassLoader;
-import java.security.cert.Certificate;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import gnu.gcj.runtime.SharedLibHelper;
-import gnu.gcj.Core;
-import gnu.java.net.protocol.core.CoreInputStream;
-
-/**
- * A secure class loader that can load classes and resources from
- * multiple locations. Given an array of <code>URL</code>s this class
- * loader will retrieve classes and resources by fetching them from
- * possible remote locations. Each <code>URL</code> is searched in
- * order in which it was added. If the file portion of the
- * <code>URL</code> ends with a '/' character then it is interpreted
- * as a base directory, otherwise it is interpreted as a jar file from
- * which the classes/resources are resolved.
- *
- * <p>New instances can be created by two static
- * <code>newInstance()</code> methods or by three public
- * contructors. Both ways give the option to supply an initial array
- * of <code>URL</code>s and (optionally) a parent classloader (that is
- * different from the standard system class loader).</p>
- *
- * <p>Normally creating a <code>URLClassLoader</code> throws a
- * <code>SecurityException</code> if a <code>SecurityManager</code> is
- * installed and the <code>checkCreateClassLoader()</code> method does
- * not return true. But the <code>newInstance()</code> methods may be
- * used by any code as long as it has permission to acces the given
- * <code>URL</code>s. <code>URLClassLoaders</code> created by the
- * <code>newInstance()</code> methods also explicitly call the
- * <code>checkPackageAccess()</code> method of
- * <code>SecurityManager</code> if one is installed before trying to
- * load a class. Note that only subclasses of
- * <code>URLClassLoader</code> can add new URLs after the
- * URLClassLoader had been created. But it is always possible to get
- * an array of all URLs that the class loader uses to resolve classes
- * and resources by way of the <code>getURLs()</code> method.</p>
- *
- * <p>Open issues:
- * <ul>
- *
- * <li>Should the URLClassLoader actually add the locations found in
- * the manifest or is this the responsibility of some other
- * loader/(sub)class? (see <a
- * href="http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html">
- * Extension Mechanism Architecture - Bundles Extensions</a>)</li>
- *
- * <li>How does <code>definePackage()</code> and sealing work
- * precisely?</li>
- *
- * <li>We save and use the security context (when a created by
- * <code>newInstance()</code> but do we have to use it in more
- * places?</li>
- *
- * <li>The use of <code>URLStreamHandler</code>s has not been tested.</li>
- *
- * </ul>
- * </p>
- *
- * @since 1.2
- *
- * @author Mark Wielaard (mark@klomp.org)
- * @author Wu Gansha (gansha.wu@intel.com)
- */
-public class URLClassLoader extends SecureClassLoader
-{
- // Class Variables
-
- /**
- * A global cache to store mappings between URLLoader and URL,
- * so we can avoid do all the homework each time the same URL
- * comes.
- * XXX - Keeps these loaders forever which prevents garbage collection.
- */
- private static HashMap urlloaders = new HashMap();
-
- /**
- * A cache to store mappings between handler factory and its
- * private protocol handler cache (also a HashMap), so we can avoid
- * create handlers each time the same protocol comes.
- */
- private static HashMap factoryCache = new HashMap(5);
-
- // Instance variables
-
- /** Locations to load classes from */
- private final Vector urls = new Vector();
-
- /**
- * Store pre-parsed information for each url into this vector: each
- * element is a URL loader. A jar file has its own class-path
- * attribute which adds to the URLs that will be searched, but this
- * does not add to the list of urls.
- */
- private final Vector urlinfos = new Vector();
-
- /** Factory used to get the protocol handlers of the URLs */
- private final URLStreamHandlerFactory factory;
-
- /**
- * The security context when created from <code>newInstance()</code>
- * or null when created through a normal constructor or when no
- * <code>SecurityManager</code> was installed.
- */
- private final AccessControlContext securityContext;
-
- // Helper classes
-
- /**
- * A <code>URLLoader</code> contains all logic to load resources from a
- * given base <code>URL</code>.
- */
- abstract static class URLLoader
- {
- /**
- * Our classloader to get info from if needed.
- */
- final URLClassLoader classloader;
-
- /**
- * The base URL from which all resources are loaded.
- */
- final URL baseURL;
-
- /**
- * A <code>CodeSource</code> without any associated certificates.
- * It is common for classes to not have certificates associated
- * with them. If they come from the same <code>URLLoader</code>
- * then it is safe to share the associated <code>CodeSource</code>
- * between them since <code>CodeSource</code> is immutable.
- */
- final CodeSource noCertCodeSource;
-
- URLLoader(URLClassLoader classloader, URL baseURL)
- {
- this(classloader, baseURL, baseURL);
- }
-
- URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
- {
- this.classloader = classloader;
- this.baseURL = baseURL;
- this.noCertCodeSource = new CodeSource(overrideURL, null);
- }
-
- /**
- * Returns a <code>Class</code> loaded by this
- * <code>URLLoader</code>, or <code>null</code> when this loader
- * either can't load the class or doesn't know how to load classes
- * at all.
- */
- Class getClass(String className)
- {
- return null;
- }
-
- /**
- * Returns a <code>Resource</code> loaded by this
- * <code>URLLoader</code>, or <code>null</code> when no
- * <code>Resource</code> with the given name exists.
- */
- abstract Resource getResource(String s);
-
- /**
- * Returns the <code>Manifest</code> associated with the
- * <code>Resource</code>s loaded by this <code>URLLoader</code> or
- * <code>null</code> there is no such <code>Manifest</code>.
- */
- Manifest getManifest()
- {
- return null;
- }
-
- Vector getClassPath()
- {
- return null;
- }
- }
-
- /**
- * A <code>Resource</code> represents a resource in some
- * <code>URLLoader</code>. It also contains all information (e.g.,
- * <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and
- * <code>InputStream</code>) that is necessary for loading resources
- * and creating classes from a <code>URL</code>.
- */
- abstract static class Resource
- {
- final URLLoader loader;
-
- Resource(URLLoader loader)
- {
- this.loader = loader;
- }
-
- /**
- * Returns the non-null <code>CodeSource</code> associated with
- * this resource.
- */
- CodeSource getCodeSource()
- {
- Certificate[] certs = getCertificates();
- if (certs == null)
- return loader.noCertCodeSource;
- else
- return new CodeSource(loader.baseURL, certs);
- }
-
- /**
- * Returns <code>Certificates</code> associated with this
- * resource, or null when there are none.
- */
- Certificate[] getCertificates()
- {
- return null;
- }
-
- /**
- * Return a <code>URL</code> that can be used to access this resource.
- */
- abstract URL getURL();
-
- /**
- * Returns the size of this <code>Resource</code> in bytes or
- * <code>-1</code> when unknown.
- */
- abstract int getLength();
-
- /**
- * Returns the non-null <code>InputStream</code> through which
- * this resource can be loaded.
- */
- abstract InputStream getInputStream() throws IOException;
- }
-
- /**
- * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
- * only loading from jar url.
- */
- static final class JarURLLoader extends URLLoader
- {
- final JarFile jarfile; // The jar file for this url
- final URL baseJarURL; // Base jar: url for all resources loaded from jar
-
- Vector classPath; // The "Class-Path" attribute of this Jar's manifest
-
- public JarURLLoader(URLClassLoader classloader, URL baseURL,
- URL absoluteUrl)
- {
- super(classloader, baseURL, absoluteUrl);
-
- // Cache url prefix for all resources in this jar url.
- String external = baseURL.toExternalForm();
- StringBuffer sb = new StringBuffer(external.length() + 6);
- sb.append("jar:");
- sb.append(external);
- sb.append("!/");
- String jarURL = sb.toString();
-
- this.classPath = null;
- URL baseJarURL = null;
- JarFile jarfile = null;
- try
- {
- baseJarURL =
- new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
-
- jarfile =
- ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
-
- Manifest manifest;
- Attributes attributes;
- String classPathString;
-
- if ((manifest = jarfile.getManifest()) != null
- && (attributes = manifest.getMainAttributes()) != null
- && ((classPathString
- = attributes.getValue(Attributes.Name.CLASS_PATH))
- != null))
- {
- this.classPath = new Vector();
-
- StringTokenizer st = new StringTokenizer(classPathString, " ");
- while (st.hasMoreElements ())
- {
- String e = st.nextToken ();
- try
- {
- URL url = new URL(baseURL, e);
- this.classPath.add(url);
- }
- catch (java.net.MalformedURLException xx)
- {
- // Give up
- }
- }
- }
- }
- catch (IOException ioe)
- {
- /* ignored */
- }
-
- this.baseJarURL = baseJarURL;
- this.jarfile = jarfile;
- }
-
- /** get resource with the name "name" in the jar url */
- Resource getResource(String name)
- {
- if (jarfile == null)
- return null;
-
- if (name.startsWith("/"))
- name = name.substring(1);
-
- JarEntry je = jarfile.getJarEntry(name);
- if (je != null)
- return new JarURLResource(this, name, je);
- else
- return null;
- }
-
- Manifest getManifest()
- {
- try
- {
- return (jarfile == null) ? null : jarfile.getManifest();
- }
- catch (IOException ioe)
- {
- return null;
- }
- }
-
- Vector getClassPath()
- {
- return classPath;
- }
- }
-
- static final class JarURLResource extends Resource
- {
- private final JarEntry entry;
- private final String name;
-
- JarURLResource(JarURLLoader loader, String name, JarEntry entry)
- {
- super(loader);
- this.entry = entry;
- this.name = name;
- }
-
- InputStream getInputStream() throws IOException
- {
- return ((JarURLLoader) loader).jarfile.getInputStream(entry);
- }
-
- int getLength()
- {
- return (int) entry.getSize();
- }
-
- Certificate[] getCertificates()
- {
- // We have to get the entry from the jar file again, because the
- // certificates will not be available until the entire entry has
- // been read.
- return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name))
- .getCertificates();
- }
-
- URL getURL()
- {
- try
- {
- return new URL(((JarURLLoader) loader).baseJarURL, name,
- loader.classloader.getURLStreamHandler("jar"));
- }
- catch (MalformedURLException e)
- {
- InternalError ie = new InternalError();
- ie.initCause(e);
- throw ie;
- }
- }
- }
-
- /**
- * Loader for remote directories.
- */
- static final class RemoteURLLoader extends URLLoader
- {
- private final String protocol;
-
- RemoteURLLoader(URLClassLoader classloader, URL url)
- {
- super(classloader, url);
- protocol = url.getProtocol();
- }
-
- /**
- * Get a remote resource.
- * Returns null if no such resource exists.
- */
- Resource getResource(String name)
- {
- try
- {
- URL url =
- new URL(baseURL, name, classloader.getURLStreamHandler(protocol));
- URLConnection connection = url.openConnection();
-
- // Open the connection and check the stream
- // just to be sure it exists.
- int length = connection.getContentLength();
- InputStream stream = connection.getInputStream();
-
- // We can do some extra checking if it is a http request
- if (connection instanceof HttpURLConnection)
- {
- int response =
- ((HttpURLConnection) connection).getResponseCode();
- if (response / 100 != 2)
- return null;
- }
-
- if (stream != null)
- return new RemoteResource(this, name, url, stream, length);
- else
- return null;
- }
- catch (IOException ioe)
- {
- return null;
- }
- }
- }
-
- /**
- * A resource from some remote location.
- */
- static final class RemoteResource extends Resource
- {
- private final URL url;
- private final InputStream stream;
- private final int length;
-
- RemoteResource(RemoteURLLoader loader, String name, URL url,
- InputStream stream, int length)
- {
- super(loader);
- this.url = url;
- this.stream = stream;
- this.length = length;
- }
-
- InputStream getInputStream() throws IOException
- {
- return stream;
- }
-
- public int getLength()
- {
- return length;
- }
-
- public URL getURL()
- {
- return url;
- }
- }
-
- /**
- * A <code>SoURLLoader</code> is a type of <code>URLLoader</code>
- * that loads classes and resources from a shared library.
- */
- final static class SoURLLoader extends URLLoader
- {
- SharedLibHelper helper;
-
- SoURLLoader(URLClassLoader classloader, URL url)
- {
- this(classloader, url, url);
- }
-
- SoURLLoader(URLClassLoader classloader, URL url, URL overrideURL)
- {
- super(classloader, url, overrideURL);
- helper = SharedLibHelper.findHelper(classloader, url.getFile(),
- noCertCodeSource, true);
- }
-
- Class getClass(String className)
- {
- return helper.findClass(className);
- }
-
- Resource getResource(String name)
- {
- URL url = helper.findResource(name);
- if (url == null)
- return null;
- return new SoResource(this, url);
- }
- }
-
- final static class SoResource extends Resource
- {
- SoResource(SoURLLoader loader, URL url)
- {
- super(loader);
- this.url = url;
- }
-
- InputStream getInputStream() throws IOException
- {
- URLConnection conn = url.openConnection();
- return conn.getInputStream();
- }
-
- public int getLength()
- {
- // FIXME we could find this by asking the core object.
- return -1;
- }
-
- public URL getURL ()
- {
- return url;
- }
-
- final URL url;
- }
-
- /**
- * A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
- * only loading from file url.
- */
- static final class FileURLLoader extends URLLoader
- {
- File dir; //the file for this file url
-
- FileURLLoader(URLClassLoader classloader, URL url, URL absoluteUrl)
- {
- super(classloader, url, absoluteUrl);
- dir = new File(absoluteUrl.getFile());
- }
-
- /** get resource with the name "name" in the file url */
- Resource getResource(String name)
- {
- try
- {
- File file = new File(dir, name).getCanonicalFile();
- if (file.exists() && !file.isDirectory())
- return new FileResource(this, file);
- }
- catch (IOException e)
- {
- // Fall through...
- }
- return null;
- }
- }
-
- static final class FileResource extends Resource
- {
- final File file;
-
- FileResource(FileURLLoader loader, File file)
- {
- super(loader);
- this.file = file;
- }
-
- InputStream getInputStream() throws IOException
- {
- // Delegate to the URL content handler mechanism to retrieve an
- // HTML representation of the directory listing if a directory
- if (file.isDirectory())
- {
- URL url = getURL();
- return url.openStream();
- }
- // Otherwise simply return a FileInputStream
- return new FileInputStream(file);
- }
-
- public int getLength()
- {
- // Delegate to the URL content handler mechanism to retrieve the
- // length of the HTML representation of the directory listing if
- // a directory, or -1 if an exception occurs opening the directory.
- if (file.isDirectory())
- {
- URL url = getURL();
- try
- {
- URLConnection connection = url.openConnection();
- return connection.getContentLength();
- }
- catch (IOException e)
- {
- return -1;
- }
- }
- // Otherwise simply return the file length
- return (int) file.length();
- }
-
- public URL getURL()
- {
- try
- {
- return file.toURL();
- }
- catch (MalformedURLException e)
- {
- InternalError ie = new InternalError();
- ie.initCause(e);
- throw ie;
- }
- }
- }
-
- /**
- * A <code>CoreURLLoader</code> is a type of <code>URLLoader</code>
- * only loading from core url.
- */
- static final class CoreURLLoader extends URLLoader
- {
- private String dir;
-
- CoreURLLoader(URLClassLoader classloader, URL url)
- {
- super(classloader, url);
- dir = baseURL.getFile();
- }
-
- /** get resource with the name "name" in the core url */
- Resource getResource(String name)
- {
- Core core = Core.find (dir + name);
- if (core != null)
- return new CoreResource(this, name, core);
- return null;
- }
- }
-
- static final class CoreResource extends Resource
- {
- private final Core core;
- private final String name;
-
- CoreResource(CoreURLLoader loader, String name, Core core)
- {
- super(loader);
- this.core = core;
- this.name = name;
- }
-
- InputStream getInputStream() throws IOException
- {
- return new CoreInputStream(core);
- }
-
- public int getLength()
- {
- return core.length;
- }
-
- public URL getURL()
- {
- try
- {
- return new URL(loader.baseURL, name,
- loader.classloader.getURLStreamHandler("core"));
- }
- catch (MalformedURLException e)
- {
- InternalError ie = new InternalError();
- ie.initCause(e);
- throw ie;
- }
- }
- }
-
- // Constructors
-
- /**
- * Creates a URLClassLoader that gets classes from the supplied URLs.
- * To determine if this classloader may be created the constructor of
- * the super class (<code>SecureClassLoader</code>) is called first, which
- * can throw a SecurityException. Then the supplied URLs are added
- * in the order given to the URLClassLoader which uses these URLs to
- * load classes and resources (after using the default parent ClassLoader).
- *
- * @param urls Locations that should be searched by this ClassLoader when
- * resolving Classes or Resources.
- * @exception SecurityException if the SecurityManager disallows the
- * creation of a ClassLoader.
- * @see SecureClassLoader
- */
- public URLClassLoader(URL[] urls) throws SecurityException
- {
- super();
- this.factory = null;
- this.securityContext = null;
- addURLs(urls);
- }
-
- /**
- * Creates a <code>URLClassLoader</code> that gets classes from the supplied
- * <code>URL</code>s.
- * To determine if this classloader may be created the constructor of
- * the super class (<code>SecureClassLoader</code>) is called first, which
- * can throw a SecurityException. Then the supplied URLs are added
- * in the order given to the URLClassLoader which uses these URLs to
- * load classes and resources (after using the supplied parent ClassLoader).
- * @param urls Locations that should be searched by this ClassLoader when
- * resolving Classes or Resources.
- * @param parent The parent class loader used before trying this class
- * loader.
- * @exception SecurityException if the SecurityManager disallows the
- * creation of a ClassLoader.
- * @exception SecurityException
- * @see SecureClassLoader
- */
- public URLClassLoader(URL[] urls, ClassLoader parent)
- throws SecurityException
- {
- super(parent);
- this.factory = null;
- this.securityContext = null;
- addURLs(urls);
- }
-
- // Package-private to avoid a trampoline constructor.
- /**
- * Package-private constructor used by the static
- * <code>newInstance(URL[])</code> method. Creates an
- * <code>URLClassLoader</code> with the given parent but without any
- * <code>URL</code>s yet. This is used to bypass the normal security
- * check for creating classloaders, but remembers the security
- * context which will be used when defining classes. The
- * <code>URL</code>s to load from must be added by the
- * <code>newInstance()</code> method in the security context of the
- * caller.
- *
- * @param securityContext the security context of the unprivileged code.
- */
- URLClassLoader(ClassLoader parent, AccessControlContext securityContext)
- {
- super(parent);
- this.factory = null;
- this.securityContext = securityContext;
- }
-
- /**
- * Creates a URLClassLoader that gets classes from the supplied URLs.
- * To determine if this classloader may be created the constructor of
- * the super class (<CODE>SecureClassLoader</CODE>) is called first, which
- * can throw a SecurityException. Then the supplied URLs are added
- * in the order given to the URLClassLoader which uses these URLs to
- * load classes and resources (after using the supplied parent ClassLoader).
- * It will use the supplied <CODE>URLStreamHandlerFactory</CODE> to get the
- * protocol handlers of the supplied URLs.
- * @param urls Locations that should be searched by this ClassLoader when
- * resolving Classes or Resources.
- * @param parent The parent class loader used before trying this class
- * loader.
- * @param factory Used to get the protocol handler for the URLs.
- * @exception SecurityException if the SecurityManager disallows the
- * creation of a ClassLoader.
- * @exception SecurityException
- * @see SecureClassLoader
- */
- public URLClassLoader(URL[] urls, ClassLoader parent,
- URLStreamHandlerFactory factory)
- throws SecurityException
- {
- super(parent);
- this.securityContext = null;
- this.factory = factory;
- addURLs(urls);
-
- // If this factory is still not in factoryCache, add it,
- // since we only support three protocols so far, 5 is enough
- // for cache initial size
- synchronized (factoryCache)
- {
- if (factory != null && factoryCache.get(factory) == null)
- factoryCache.put(factory, new HashMap(5));
- }
- }
-
- // Methods
-
- /**
- * Adds a new location to the end of the internal URL store.
- * @param newUrl the location to add
- */
- protected void addURL(URL newUrl)
- {
- urls.add(newUrl);
- addURLImpl(newUrl);
- }
-
- private void addURLImpl(URL newUrl)
- {
- synchronized (this)
- {
- if (newUrl == null)
- return; // Silently ignore...
-
- // Reset the toString() value.
- thisString = null;
-
- // Check global cache to see if there're already url loader
- // for this url.
- URLLoader loader = (URLLoader) urlloaders.get(newUrl);
- if (loader == null)
- {
- String file = newUrl.getFile();
- String protocol = newUrl.getProtocol();
-
- // If we have a file: URL, we want to make it absolute
- // here, before we decide whether it is really a jar.
- URL absoluteURL;
- if ("file".equals (protocol))
- {
- File dir = new File(file);
- URL absUrl;
- try
- {
- absoluteURL = dir.getCanonicalFile().toURL();
- }
- catch (IOException ignore)
- {
- try
- {
- absoluteURL = dir.getAbsoluteFile().toURL();
- }
- catch (MalformedURLException _)
- {
- // This really should not happen.
- absoluteURL = newUrl;
- }
- }
- }
- else
- {
- // This doesn't hurt, and it simplifies the logic a
- // little.
- absoluteURL = newUrl;
- }
-
- // Check that it is not a directory
- if ("gcjlib".equals(protocol))
- loader = new SoURLLoader(this, newUrl);
- else if (! (file.endsWith("/") || file.endsWith(File.separator)))
- loader = new JarURLLoader(this, newUrl, absoluteURL);
- else if ("file".equals(protocol))
- loader = new FileURLLoader(this, newUrl, absoluteURL);
- else if ("core".equals(protocol))
- loader = new CoreURLLoader(this, newUrl);
- else
- loader = new RemoteURLLoader(this, newUrl);
-
- // Cache it.
- urlloaders.put(newUrl, loader);
- }
-
- urlinfos.add(loader);
-
- Vector extraUrls = loader.getClassPath();
- if (extraUrls != null)
- {
- Iterator it = extraUrls.iterator();
- while (it.hasNext())
- {
- URL url = (URL)it.next();
- URLLoader extraLoader = (URLLoader) urlloaders.get(url);
- if (! urlinfos.contains (extraLoader))
- addURLImpl(url);
- }
- }
-
- }
- }
-
- /**
- * Adds an array of new locations to the end of the internal URL
- * store. Called from the the constructors. Should not call to the
- * protected addURL() method since that can be overridden and
- * subclasses are not yet in a good state at this point.
- * jboss 4.0.3 for example depends on this.
- *
- * @param newUrls the locations to add
- */
- private void addURLs(URL[] newUrls)
- {
- for (int i = 0; i < newUrls.length; i++)
- {
- urls.add(newUrls[i]);
- addURLImpl(newUrls[i]);
- }
- }
-
- /**
- * Look in both Attributes for a given value. The first Attributes
- * object, if not null, has precedence.
- */
- private String getAttributeValue(Attributes.Name name, Attributes first,
- Attributes second)
- {
- String result = null;
- if (first != null)
- result = first.getValue(name);
- if (result == null)
- result = second.getValue(name);
- return result;
- }
-
- /**
- * Defines a Package based on the given name and the supplied manifest
- * information. The manifest indicates the title, version and
- * vendor information of the specification and implementation and whether the
- * package is sealed. If the Manifest indicates that the package is sealed
- * then the Package will be sealed with respect to the supplied URL.
- *
- * @param name The name of the package
- * @param manifest The manifest describing the specification,
- * implementation and sealing details of the package
- * @param url the code source url to seal the package
- * @return the defined Package
- * @throws IllegalArgumentException If this package name already exists
- * in this class loader
- */
- protected Package definePackage(String name, Manifest manifest, URL url)
- throws IllegalArgumentException
- {
- // Compute the name of the package as it may appear in the
- // Manifest.
- StringBuffer xform = new StringBuffer(name);
- for (int i = xform.length () - 1; i >= 0; --i)
- if (xform.charAt(i) == '.')
- xform.setCharAt(i, '/');
- xform.append('/');
- String xformName = xform.toString();
-
- Attributes entryAttr = manifest.getAttributes(xformName);
- Attributes attr = manifest.getMainAttributes();
-
- String specTitle
- = getAttributeValue(Attributes.Name.SPECIFICATION_TITLE,
- entryAttr, attr);
- String specVersion
- = getAttributeValue(Attributes.Name.SPECIFICATION_VERSION,
- entryAttr, attr);
- String specVendor
- = getAttributeValue(Attributes.Name.SPECIFICATION_VENDOR,
- entryAttr, attr);
- String implTitle
- = getAttributeValue(Attributes.Name.IMPLEMENTATION_TITLE,
- entryAttr, attr);
- String implVersion
- = getAttributeValue(Attributes.Name.IMPLEMENTATION_VERSION,
- entryAttr, attr);
- String implVendor
- = getAttributeValue(Attributes.Name.IMPLEMENTATION_VENDOR,
- entryAttr, attr);
-
- // Look if the Manifest indicates that this package is sealed
- // XXX - most likely not completely correct!
- // Shouldn't we also check the sealed attribute of the complete jar?
- // http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html#bundled
- // But how do we get that jar manifest here?
- String sealed = attr.getValue(Attributes.Name.SEALED);
- if ("false".equals(sealed))
- // make sure that the URL is null so the package is not sealed
- url = null;
-
- return definePackage(name,
- specTitle, specVendor, specVersion,
- implTitle, implVendor, implVersion,
- url);
- }
-
- /**
- * Finds (the first) class by name from one of the locations. The locations
- * are searched in the order they were added to the URLClassLoader.
- *
- * @param className the classname to find
- * @exception ClassNotFoundException when the class could not be found or
- * loaded
- * @return a Class object representing the found class
- */
- protected Class findClass(final String className)
- throws ClassNotFoundException
- {
- // Just try to find the resource by the (almost) same name
- String resourceName = className.replace('.', '/') + ".class";
- int max = urlinfos.size();
- Resource resource = null;
- for (int i = 0; i < max && resource == null; i++)
- {
- URLLoader loader = (URLLoader)urlinfos.elementAt(i);
- if (loader == null)
- continue;
-
- Class k = loader.getClass(className);
- if (k != null)
- return k;
-
- resource = loader.getResource(resourceName);
- }
- if (resource == null)
- {
- String message = className + " not found";
- // Calling this.toString() during VM startup when a
- // security manager is in force causes the stack to
- // be unwound before it can properly be decoded.
- if (Thread.currentThread() != null)
- message += " in " + this;
- throw new ClassNotFoundException(message);
- }
-
- // Try to read the class data, create the CodeSource, Package and
- // construct the class (and watch out for those nasty IOExceptions)
- try
- {
- byte[] data;
- InputStream in = resource.getInputStream();
- try
- {
- int length = resource.getLength();
- if (length != -1)
- {
- // We know the length of the data.
- // Just try to read it in all at once
- data = new byte[length];
- int pos = 0;
- while (length - pos > 0)
- {
- int len = in.read(data, pos, length - pos);
- if (len == -1)
- throw new EOFException("Not enough data reading from: "
- + in);
- pos += len;
- }
- }
- else
- {
- // We don't know the data length.
- // Have to read it in chunks.
- ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
- byte[] b = new byte[4096];
- int l = 0;
- while (l != -1)
- {
- l = in.read(b);
- if (l != -1)
- out.write(b, 0, l);
- }
- data = out.toByteArray();
- }
- }
- finally
- {
- in.close();
- }
- final byte[] classData = data;
-
- // Now get the CodeSource
- final CodeSource source = resource.getCodeSource();
-
- // Find out package name
- String packageName = null;
- int lastDot = className.lastIndexOf('.');
- if (lastDot != -1)
- packageName = className.substring(0, lastDot);
-
- if (packageName != null && getPackage(packageName) == null)
- {
- // define the package
- Manifest manifest = resource.loader.getManifest();
- if (manifest == null)
- definePackage(packageName, null, null, null, null, null, null,
- null);
- else
- definePackage(packageName, manifest, resource.loader.baseURL);
- }
-
- // And finally construct the class!
- SecurityManager sm = System.getSecurityManager();
- Class result = null;
- if (sm != null && securityContext != null)
- {
- result = (Class)AccessController.doPrivileged
- (new PrivilegedAction()
- {
- public Object run()
- {
- return defineClass(className, classData,
- 0, classData.length,
- source);
- }
- }, securityContext);
- }
- else
- result = defineClass(className, classData, 0, classData.length, source);
-
- // Avoid NullPointerExceptions.
- Certificate[] resourceCertificates = resource.getCertificates();
- if(resourceCertificates != null)
- super.setSigners(result, resourceCertificates);
-
- return result;
- }
- catch (IOException ioe)
- {
- ClassNotFoundException cnfe;
- cnfe = new ClassNotFoundException(className + " not found in " + this);
- cnfe.initCause(ioe);
- throw cnfe;
- }
- }
-
- // Cached String representation of this URLClassLoader
- private String thisString;
-
- /**
- * Returns a String representation of this URLClassLoader giving the
- * actual Class name, the URLs that are searched and the parent
- * ClassLoader.
- */
- public String toString()
- {
- synchronized (this)
- {
- if (thisString == null)
- {
- StringBuffer sb = new StringBuffer();
- sb.append(this.getClass().getName());
- sb.append("{urls=[" );
- URL[] thisURLs = getURLs();
- for (int i = 0; i < thisURLs.length; i++)
- {
- sb.append(thisURLs[i]);
- if (i < thisURLs.length - 1)
- sb.append(',');
- }
- sb.append(']');
- sb.append(", parent=");
- sb.append(getParent());
- sb.append('}');
- thisString = sb.toString();
- }
- return thisString;
- }
- }
-
- /**
- * Finds the first occurrence of a resource that can be found. The locations
- * are searched in the order they were added to the URLClassLoader.
- *
- * @param resourceName the resource name to look for
- * @return the URLResource for the resource if found, null otherwise
- */
- private Resource findURLResource(String resourceName)
- {
- int max = urlinfos.size();
- for (int i = 0; i < max; i++)
- {
- URLLoader loader = (URLLoader) urlinfos.elementAt(i);
- if (loader == null)
- continue;
-
- Resource resource = loader.getResource(resourceName);
- if (resource != null)
- return resource;
- }
- return null;
- }
-
- /**
- * Finds the first occurrence of a resource that can be found.
- *
- * @param resourceName the resource name to look for
- * @return the URL if found, null otherwise
- */
- public URL findResource(String resourceName)
- {
- Resource resource = findURLResource(resourceName);
- if (resource != null)
- return resource.getURL();
-
- // Resource not found
- return null;
- }
-
- /**
- * If the URLStreamHandlerFactory has been set this return the appropriate
- * URLStreamHandler for the given protocol, if not set returns null.
- *
- * @param protocol the protocol for which we need a URLStreamHandler
- * @return the appropriate URLStreamHandler or null
- */
- URLStreamHandler getURLStreamHandler(String protocol)
- {
- if (factory == null)
- return null;
-
- URLStreamHandler handler;
- synchronized (factoryCache)
- {
- // Check if there're handler for the same protocol in cache.
- HashMap cache = (HashMap) factoryCache.get(factory);
- handler = (URLStreamHandler) cache.get(protocol);
- if (handler == null)
- {
- // Add it to cache.
- handler = factory.createURLStreamHandler(protocol);
- cache.put(protocol, handler);
- }
- }
- return handler;
- }
-
- /**
- * Finds all the resources with a particular name from all the locations.
- *
- * @param resourceName the name of the resource to lookup
- * @return a (possible empty) enumeration of URLs where the resource can be
- * found
- * @exception IOException when an error occurs accessing one of the
- * locations
- */
- public Enumeration findResources(String resourceName)
- throws IOException
- {
- Vector resources = new Vector();
- int max = urlinfos.size();
- for (int i = 0; i < max; i++)
- {
- URLLoader loader = (URLLoader) urlinfos.elementAt(i);
- Resource resource = loader.getResource(resourceName);
- if (resource != null)
- resources.add(resource.getURL());
- }
- return resources.elements();
- }
-
- /**
- * Returns the permissions needed to access a particular code
- * source. These permissions includes those returned by
- * <code>SecureClassLoader.getPermissions()</code> and the actual
- * permissions to access the objects referenced by the URL of the
- * code source. The extra permissions added depend on the protocol
- * and file portion of the URL in the code source. If the URL has
- * the "file" protocol ends with a '/' character then it must be a
- * directory and a file Permission to read everything in that
- * directory and all subdirectories is added. If the URL had the
- * "file" protocol and doesn't end with a '/' character then it must
- * be a normal file and a file permission to read that file is
- * added. If the <code>URL</code> has any other protocol then a
- * socket permission to connect and accept connections from the host
- * portion of the URL is added.
- *
- * @param source The codesource that needs the permissions to be accessed
- * @return the collection of permissions needed to access the code resource
- * @see java.security.SecureClassLoader#getPermissions(CodeSource)
- */
- protected PermissionCollection getPermissions(CodeSource source)
- {
- // XXX - This implementation does exactly as the Javadoc describes.
- // But maybe we should/could use URLConnection.getPermissions()?
- // First get the permissions that would normally be granted
- PermissionCollection permissions = super.getPermissions(source);
-
- // Now add any extra permissions depending on the URL location.
- URL url = source.getLocation();
- String protocol = url.getProtocol();
- if (protocol.equals("file"))
- {
- String file = url.getFile();
-
- // If the file end in / it must be an directory.
- if (file.endsWith("/") || file.endsWith(File.separator))
- {
- // Grant permission to read everything in that directory and
- // all subdirectories.
- permissions.add(new FilePermission(file + "-", "read"));
- }
- else
- {
- // It is a 'normal' file.
- // Grant permission to access that file.
- permissions.add(new FilePermission(file, "read"));
- }
- }
- else
- {
- // Grant permission to connect to and accept connections from host
- String host = url.getHost();
- if (host != null)
- permissions.add(new SocketPermission(host, "connect,accept"));
- }
-
- return permissions;
- }
-
- /**
- * Returns all the locations that this class loader currently uses the
- * resolve classes and resource. This includes both the initially supplied
- * URLs as any URLs added later by the loader.
- * @return All the currently used URLs
- */
- public URL[] getURLs()
- {
- return (URL[]) urls.toArray(new URL[urls.size()]);
- }
-
- /**
- * Creates a new instance of a <code>URLClassLoader</code> that gets
- * classes from the supplied <code>URL</code>s. This class loader
- * will have as parent the standard system class loader.
- *
- * @param urls the initial URLs used to resolve classes and
- * resources
- *
- * @return the class loader
- *
- * @exception SecurityException when the calling code does not have
- * permission to access the given <code>URL</code>s
- */
- public static URLClassLoader newInstance(URL[] urls)
- throws SecurityException
- {
- return newInstance(urls, null);
- }
-
- /**
- * Creates a new instance of a <code>URLClassLoader</code> that gets
- * classes from the supplied <code>URL</code>s and with the supplied
- * loader as parent class loader.
- *
- * @param urls the initial URLs used to resolve classes and
- * resources
- * @param parent the parent class loader
- *
- * @return the class loader
- *
- * @exception SecurityException when the calling code does not have
- * permission to access the given <code>URL</code>s
- */
- public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
- throws SecurityException
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null)
- return new URLClassLoader(urls, parent);
- else
- {
- final Object securityContext = sm.getSecurityContext();
-
- // XXX - What to do with anything else then an AccessControlContext?
- if (! (securityContext instanceof AccessControlContext))
- throw new SecurityException("securityContext must be AccessControlContext: "
- + securityContext);
-
- URLClassLoader loader =
- (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- return new URLClassLoader(parent,
- (AccessControlContext) securityContext);
- }
- });
- loader.addURLs(urls);
- return loader;
- }
- }
-}
diff --git a/libjava/sources.am b/libjava/sources.am
index fea09f26961..418bd8d7c52 100644
--- a/libjava/sources.am
+++ b/libjava/sources.am
@@ -1338,6 +1338,7 @@ classpath/gnu/java/net/loader/FileResource.java \
classpath/gnu/java/net/loader/FileURLLoader.java \
classpath/gnu/java/net/loader/JarURLLoader.java \
classpath/gnu/java/net/loader/JarURLResource.java \
+gnu/java/net/loader/Load_gcjlib.java \
classpath/gnu/java/net/loader/RemoteResource.java \
classpath/gnu/java/net/loader/RemoteURLLoader.java \
classpath/gnu/java/net/loader/Resource.java \
@@ -4846,7 +4847,7 @@ classpath/java/net/SocketTimeoutException.java \
classpath/java/net/URI.java \
classpath/java/net/URISyntaxException.java \
classpath/java/net/URL.java \
-java/net/URLClassLoader.java \
+classpath/java/net/URLClassLoader.java \
classpath/java/net/URLConnection.java \
classpath/java/net/URLDecoder.java \
classpath/java/net/URLEncoder.java \
OpenPOWER on IntegriCloud