Connection.java (getJarFile): download and cache remote jar files.

* gnu/gcj/protocol/jar/Connection.java (getJarFile): download and
	cache remote jar files.
	* gnu/gcj/runtime/VMClassLoader.java: Don't construct jar URL, only
	add File.separator to URL when it is a directory.
	* java/lang/ClassLoader.java: Add Classpath javadoc.
	(parent): final.
	(getParent): Add (disabled) security check.
	(findLibrary): New default method.
	* java/net/JarURLConnection.java (getManifest): Implement.
	(getInputStream): Only create InputStream when entry exists.
	(getHeaders): Only use jarFileURLConnection or JarEntry to set length
	when they exist.
	* java/net/URLClassLoader.java: New/Rewritten version from Classpath.

From-SVN: r59949
This commit is contained in:
Mark Wielaard 2002-12-09 00:04:00 +00:00 committed by Mark Wielaard
parent 24632117ce
commit e825ca7ff5
6 changed files with 1099 additions and 365 deletions

View File

@ -1,3 +1,19 @@
2002-12-08 Mark Wielaard <mark@klomp.org>
* gnu/gcj/protocol/jar/Connection.java (getJarFile): download and
cache remote jar files.
* gnu/gcj/runtime/VMClassLoader.java: Don't construct jar URL, only
add File.separator to URL when it is a directory.
* java/lang/ClassLoader.java: Add Classpath javadoc.
(parent): final.
(getParent): Add (disabled) security check.
(findLibrary): New default method.
* java/net/JarURLConnection.java (getManifest): Implement.
(getInputStream): Only create InputStream when entry exists.
(getHeaders): Only use jarFileURLConnection or JarEntry to set length
when they exist.
* java/net/URLClassLoader.java: New/Rewritten version from Classpath.
2002-12-08 Mark Wielaard <mark@klomp.org>
* java/util/ResourceBundle.java (resourceBundleCache): Not final.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1999 Free Software Foundation
/* Copyright (C) 1999, 2002 Free Software Foundation
This file is part of libgcj.
@ -9,19 +9,21 @@ details. */
package gnu.gcj.protocol.jar;
import java.net.URL;
import java.net.URLConnection;
import java.net.JarURLConnection;
import java.net.URLStreamHandler;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.io.IOException;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;
import java.util.Hashtable;
/**
* Written using on-line Java Platform 1.2 API Specification.
* Status: Needs a way to download jar files and store them in the local file
* system. I don't know how to do that in a portable way. For now, it can only handle
* connections to a jar:file: url's.
*
* @author Kresten Krab Thorup <krab@gnu.org>
* @date Aug 10, 1999.
@ -70,14 +72,19 @@ public class Connection extends JarURLConnection
}
else
{
/*
FIXME: Here we need to download and cache the jar
file in the local file system! Stupid design. Why
can't we just create a JarFile from a bag of bytes?
*/
throw new java.io.IOException("cannot create jar file from " +
jarFileURL);
URLConnection urlconn = jarFileURL.openConnection();
InputStream is = urlconn.getInputStream();
byte[] buf = new byte[4*1024];
File f = File.createTempFile("cache", "jar");
FileOutputStream fos = new FileOutputStream(f);
int len = 0;
while((len = is.read(buf)) != -1)
fos.write(buf, 0, len);
fos.close();
// Always verify the Manifest, open read only and delete when done.
// XXX ZipFile.OPEN_DELETE not yet implemented.
// jf = new JarFile(f, true, ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
jarfile = new JarFile(f, true, ZipFile.OPEN_READ);
}
return jarfile;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1999, 2001 Free Software Foundation
/* Copyright (C) 1999, 2001, 2002 Free Software Foundation
This file is part of libgcj.
@ -33,23 +33,10 @@ public final class VMClassLoader extends java.net.URLClassLoader
String e = st.nextToken ();
try
{
if (e.endsWith(".jar") || e.endsWith (".zip"))
{
File archive = new File (e);
try {
p.addElement(new URL("jar", "", -1, "file://"
+ archive.getCanonicalPath ()
+ "!/"));
} catch (IOException ex) {
// empty
}
}
else if (e.endsWith ("/"))
p.addElement (new URL("file", "", -1, e));
else if (new File (e).isDirectory ())
p.addElement (new URL("file", "", -1, e + "/"));
if (!e.endsWith (File.separator) && new File (e).isDirectory ())
p.addElement (new URL("file", "", -1, e + File.separator));
else
/* Ignore path element. */;
p.addElement (new URL("file", "", -1, e));
}
catch (java.net.MalformedURLException x)
{

View File

@ -13,7 +13,6 @@ package java.lang;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permission;
@ -23,13 +22,68 @@ import java.security.ProtectionDomain;
import java.util.*;
/**
* The class <code>ClassLoader</code> is intended to be subclassed by
* applications in order to describe new ways of loading classes,
* such as over the network.
* The ClassLoader is a way of customizing the way Java gets its classes
* and loads them into memory. The verifier and other standard Java things
* still run, but the ClassLoader is allowed great flexibility in determining
* where to get the classfiles and when to load and resolve them. For that
* matter, a custom ClassLoader can perform on-the-fly code generation or
* modification!
*
* @author Kresten Krab Thorup
* <p>Every classloader has a parent classloader that is consulted before
* the 'child' classloader when classes or resources should be loaded.
* This is done to make sure that classes can be loaded from an hierarchy of
* multiple classloaders and classloaders do not accidentially redefine
* already loaded classes by classloaders higher in the hierarchy.
*
* <p>The grandparent of all classloaders is the bootstrap classloader, which
* loads all the standard system classes as implemented by GNU Classpath. The
* other special classloader is the system classloader (also called
* application classloader) that loads all classes from the CLASSPATH
* (<code>java.class.path</code> system property). The system classloader
* is responsible for finding the application classes from the classpath,
* and delegates all requests for the standard library classes to its parent
* the bootstrap classloader. Most programs will load all their classes
* through the system classloaders.
*
* <p>The bootstrap classloader in GNU Classpath is implemented as a couple of
* static (native) methods on the package private class
* <code>java.lang.VMClassLoader</code>, the system classloader is an
* instance of <code>gnu.java.lang.SystemClassLoader</code>
* (which is a subclass of <code>java.net.URLClassLoader</code>).
*
* <p>Users of a <code>ClassLoader</code> will normally just use the methods
* <ul>
* <li> <code>loadClass()</code> to load a class.</li>
* <li> <code>getResource()</code> or <code>getResourceAsStream()</code>
* to access a resource.</li>
* <li> <code>getResources()</code> to get an Enumeration of URLs to all
* the resources provided by the classloader and its parents with the
* same name.</li>
* </ul>
*
* <p>Subclasses should implement the methods
* <ul>
* <li> <code>findClass()</code> which is called by <code>loadClass()</code>
* when the parent classloader cannot provide a named class.</li>
* <li> <code>findResource()</code> which is called by
* <code>getResource()</code> when the parent classloader cannot provide
* a named resource.</li>
* <li> <code>findResources()</code> which is called by
* <code>getResource()</code> to combine all the resources with the
* same name from the classloader and its parents.</li>
* <li> <code>findLibrary()</code> which is called by
* <code>Runtime.loadLibrary()</code> when a class defined by the
* classloader wants to load a native library.</li>
* </ul>
*
* @author John Keiser
* @author Mark Wielaard
* @author Eric Blake
* @author Kresten Krab Thorup
* @see Class
* @since 1.0
* @status still missing 1.4 functionality
*/
public abstract class ClassLoader
{
/**
@ -73,12 +127,40 @@ public abstract class ClassLoader
// Package visible for use by Class.
Map classAssertionStatus;
private ClassLoader parent;
/**
* The classloader that is consulted before this classloader.
* If null then the parent is the bootstrap classloader.
*/
private final ClassLoader parent;
/**
* All packages defined by this classloader. It is not private in order to
* allow native code (and trusted subclasses) access to this field.
*/
private HashMap definedPackages = new HashMap();
/**
* Returns the parent of this classloader. If the parent of this
* classloader is the bootstrap classloader then this method returns
* <code>null</code>. A security check may be performed on
* <code>RuntimePermission("getClassLoader")</code>.
*
* @throws SecurityException if the security check fails
* @since 1.2
*/
public final ClassLoader getParent ()
{
/* FIXME: security */
// Check if we may return the parent classloader
SecurityManager sm = System.getSecurityManager();
if (sm != null)
{
/* FIXME: security, getClassContext() not implemented.
Class c = VMSecurityManager.getClassContext()[1];
ClassLoader cl = c.getClassLoader();
if (cl != null && cl != this)
sm.checkPermission(new RuntimePermission("getClassLoader"));
*/
}
return parent;
}
@ -449,7 +531,8 @@ public abstract class ClassLoader
else
{
InternalError e
= new InternalError ("unexpected exception during linking");
= new InternalError ("unexpected exception during linking: "
+ clazz.getName());
e.initCause (x);
throw e;
}
@ -521,6 +604,8 @@ public abstract class ClassLoader
* null when the package is not defined by this classloader or one of its
* parents.
*
* @param name the package name to find
* @return the package, if defined
* @since 1.2
*/
protected Package getPackage(String name)
@ -546,6 +631,7 @@ public abstract class ClassLoader
/**
* Returns all Package objects defined by this classloader and its parents.
*
* @return an array of all defined packages
* @since 1.2
*/
protected Package[] getPackages()
@ -577,6 +663,26 @@ public abstract class ClassLoader
return allPackages;
}
/**
* Called by <code>Runtime.loadLibrary()</code> to get an absolute path
* to a (system specific) library that was requested by a class loaded
* by this classloader. The default implementation returns
* <code>null</code>. It should be implemented by subclasses when they
* have a way to find the absolute path to a library. If this method
* returns null the library is searched for in the default locations
* (the directories listed in the <code>java.library.path</code> system
* property).
*
* @param name the (system specific) name of the requested library
* @return the full pathname to the requested library, or null
* @see Runtime#loadLibrary()
* @since 1.2
*/
protected String findLibrary(String name)
{
return null;
}
/**
* Returns a class found in a system-specific way, typically
* via the <code>java.class.path</code> system property. Loads the

View File

@ -134,7 +134,11 @@ public abstract class JarURLConnection extends URLConnection
if (jarfile != null)
{
// this is the easy way...
return jarfile.getInputStream (jarfile.getEntry (element));
ZipEntry entry = jarfile.getEntry(element);
if (entry != null)
return jarfile.getInputStream (entry);
else
return null;
}
else
{
@ -320,12 +324,17 @@ public abstract class JarURLConnection extends URLConnection
// to add others later and for consistency, we'll implement it this way.
// Add the only header we know about right now: Content-length.
long len;
long len = -1;
if (element == null)
len = jarFileURLConnection.getContentLength ();
if (jarFileURLConnection != null)
len = jarFileURLConnection.getContentLength ();
else
len = getJarEntry ().getSize ();
{
JarEntry entry = getJarEntry();
if (entry != null)
len = entry.getSize ();
}
String line = "Content-length: " + len;
hdrVec.addElement(line);
@ -381,7 +390,6 @@ public abstract class JarURLConnection extends URLConnection
{
JarFile file = getJarFile ();
// FIXME: implement this
return null;
return (file != null) ? file.getManifest() : null;
}
}

File diff suppressed because it is too large Load Diff