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:
parent
24632117ce
commit
e825ca7ff5
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user