[cp-patches] FYI: transform plugin's gappletviewer reference

2006-08-17 Thread Thomas Fitzsimmons

Hi,

I committed this patch to fix PR 28537.

Tom

2006-08-17  Thomas Fitzsimmons  <[EMAIL PROTECTED]>

PR classpath/28537
* native/plugin/Makefile.am (libgcjwebplugin_la_CXXFLAGS):
Transform gappletviewer name using program_transform_name.
Index: native/plugin/Makefile.am
===
RCS file: /sources/classpath/classpath/native/plugin/Makefile.am,v
retrieving revision 1.6
diff -u -r1.6 Makefile.am
--- native/plugin/Makefile.am	5 Jul 2006 21:35:21 -	1.6
+++ native/plugin/Makefile.am	17 Aug 2006 20:06:45 -
@@ -3,7 +3,7 @@
 libgcjwebplugin_la_SOURCES = gcjwebplugin.cc
 
 libgcjwebplugin_la_CXXFLAGS = \
-	-Wall -DAPPLETVIEWER_EXECUTABLE="\"$(bindir)/gappletviewer\"" \
+	-Wall -DAPPLETVIEWER_EXECUTABLE="\"$(bindir)/`echo gappletviewer | sed '$(program_transform_name)'`\"" \
 	$(MOZILLA_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
 
 libgcjwebplugin_la_LDFLAGS = -avoid-version \


[cp-patches] FYI: FileSystemView & BasicFileChooserUI fix

2006-08-17 Thread Jeroen Frijters
Hi,

I committed the attached patch.

-Object path = filechooser.getCurrentDirectory();
+File path = filechooser.getCurrentDirectory();
 if (path != null)
-  parentPath =
path.toString().substring(path.toString().lastIndexOf("/"));
+  parentPath = path.getParent();

Why do we have crap like this in cvs? There's really no excuse for code
this badly written.

Regards,
Jeroen

2006-08-17  Jeroen Frijters  <[EMAIL PROTECTED]>

* javax/swing/filechooser/FileSystemView.java
(getFileSystemView): Always return UnixFileSystemView, since
that's the only one we got. Marked with NotImplementedException.
* javax/swing/plaf/basic/BasicFileChooserUI.java
(mouseClicked, installUI): Don't parse path by hand.
Index: javax/swing/filechooser/FileSystemView.java
===
RCS file: 
/cvsroot/classpath/classpath/javax/swing/filechooser/FileSystemView.java,v
retrieving revision 1.11
diff -u -r1.11 FileSystemView.java
--- javax/swing/filechooser/FileSystemView.java 2 Aug 2006 11:31:44 -   
1.11
+++ javax/swing/filechooser/FileSystemView.java 17 Aug 2006 15:58:15 -
@@ -37,6 +37,8 @@
 
 package javax.swing.filechooser;
 
+import gnu.classpath.NotImplementedException;
+
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -169,16 +171,12 @@
* @return A default [EMAIL PROTECTED] FileSystemView} appropriate for the 
platform.
*/
   public static FileSystemView getFileSystemView()
+throws NotImplementedException
   {
 if (defaultFileSystemView == null)
   {
-if (File.separator.equals("/"))
-  defaultFileSystemView = new UnixFileSystemView();
-// FIXME: need to implement additional views
-// else if (File.Separator.equals("\"))
-//   return new Win32FileSystemView();
-// else 
-//   return new GenericFileSystemView();
+// FIXME: We need to support other file systems too.
+defaultFileSystemView = new UnixFileSystemView();
   }
 return defaultFileSystemView;
   }
Index: javax/swing/plaf/basic/BasicFileChooserUI.java
===
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java,v
retrieving revision 1.29
diff -u -r1.29 BasicFileChooserUI.java
--- javax/swing/plaf/basic/BasicFileChooserUI.java  2 Aug 2006 15:20:37 
-   1.29
+++ javax/swing/plaf/basic/BasicFileChooserUI.java  17 Aug 2006 15:45:10 
-
@@ -444,10 +444,10 @@
   setDirectory(null);
 }
   lastSelected = path;
-  parentPath = path.substring(0, path.lastIndexOf("/") + 1);
+  parentPath = f.getParent();

   if (f.isFile())
-setFileName(path.substring(path.lastIndexOf("/") + 1));
+setFileName(f.getName());
   else if (filechooser.getFileSelectionMode() != 
   JFileChooser.FILES_ONLY)
 setFileName(path);
@@ -827,9 +827,9 @@
 installComponents(fc);
 installListeners(fc);
 
-Object path = filechooser.getCurrentDirectory();
+File path = filechooser.getCurrentDirectory();
 if (path != null)
-  parentPath = 
path.toString().substring(path.toString().lastIndexOf("/"));
+  parentPath = path.getParent();
   }
   }
 


Re: [cp-patches] Re: FYI: Vector fixlet

2006-08-17 Thread Tom Tromey
>> If it is a bogus test, please remove it.
>> Thanks.

Stuart> Wouldn't it be better to modify the test to test that the
Stuart> outcome *is* whatever the RI gives in whatever the situation
Stuart> is?

Yeah :-)

Tom



[cp-patches] Re: FYI: Vector fixlet

2006-08-17 Thread Stuart Ballard
Tom Tromey  redhat.com> writes:

> If it is a bogus test, please remove it.
> Thanks.

Wouldn't it be better to modify the test to test that the outcome *is* whatever
the RI gives in whatever the situation is?

Stuart.




Re: [cp-patches] FYI: Vector fixlet

2006-08-17 Thread Tom Tromey
> "Roman" == Roman Kennke <[EMAIL PROTECTED]> writes:

Roman> Yes, but the JDK also fails this test, so I didn't worry about it.

If it is a bogus test, please remove it.
Thanks.

Tom



[cp-patches] FYI: JComponent fixlet

2006-08-17 Thread Roman Kennke
This makes JComponent.scrollRectToVisible() behave more elegantly when 
there are non-JComponents in the tree. This can be important, because 
there actually are some of these even in Swing (like the CellRendererPane).


2006-08-17  Roman Kennke  <[EMAIL PROTECTED]>

* javax/swing/JComponent.java
(scrollRectToVisible): Handle intermediate non-JComponents
more gracefully.

/Roman
Index: javax/swing/JComponent.java
===
RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v
retrieving revision 1.142
diff -u -1 -2 -r1.142 JComponent.java
--- javax/swing/JComponent.java	29 Jul 2006 22:33:51 -	1.142
+++ javax/swing/JComponent.java	17 Aug 2006 15:11:18 -
@@ -2568,25 +2568,25 @@
 
 // This is step 4 from above comment.  KeyboardManager maintains mappings
 // related to WHEN_IN_FOCUSED_WINDOW bindings so that we don't have to 
 // traverse the containment hierarchy each time.
 if (KeyboardManager.getManager().processKeyStroke(current, keyStroke, e))
   e.consume();
   }
 
   protected boolean processKeyBinding(KeyStroke ks,
   KeyEvent e,
   int condition,
   boolean pressed)
-  { 
+  {
 if (isEnabled())
   {
 Action act = null;
 Object cmd = null;
 InputMap map = getInputMap(condition);
 if (map != null)
   {
 cmd = map.get(ks);
 if (cmd != null)
   {
 if (cmd instanceof ActionListenerProxy)
   act = (Action) cmd;
@@ -2732,27 +2732,43 @@
 RepaintManager.currentManager(this).addInvalidComponent(this);
   }
   }
 
   /**
* Calls scrollRectToVisible on the component's parent. 
* Components which can service this call should override.
*
* @param r The rectangle to make visible
*/
   public void scrollRectToVisible(Rectangle r)
   {
-Component p = getParent();
-if (p instanceof JComponent)
-  ((JComponent) p).scrollRectToVisible(r);
+// Search nearest JComponent.
+int xOffs = getX();
+int yOffs = getY();
+Component p;
+for (p = getParent(); p != null && ! (p instanceof JComponent);
+ p = p.getParent())
+  {
+xOffs += p.getX();
+yOffs += p.getY();
+  }
+if (p != null)
+  {
+r.x += xOffs;
+r.y += yOffs;
+JComponent jParent = (JComponent) p;
+jParent.scrollRectToVisible(r);
+r.x -= xOffs;
+r.y -= yOffs;
+  }
   }
 
   /**
* Set the value of the [EMAIL PROTECTED] #alignmentX} property.
*
* @param a The new value of the property
*/
   public void setAlignmentX(float a)
   {
 if (a < 0.0F)
   alignmentX = 0.0F;
 else if (a > 1.0)


[cp-patches] FYI: RepaintManager cleanup

2006-08-17 Thread Roman Kennke
This is a cleanup. I disabled some parts of RepaintManager some time ago 
because I suspected that it doesn't improve painting performance, and 
now I rip these parts out. This also means some slight performance 
improvement, because the rectangle translation is done on the fly.


2006-08-17  Roman Kennke  <[EMAIL PROTECTED]>

* javax/swing/RepaintManager.java
(blitBuffer): Removed. This is now done in commitBuffer().
(commitBuffer): Always paint on the root window or applet.
No need to look for intermediate heavyweights. Optimized
rectangle translation.
(commitRemainingBuffers): Removed. Not needed anymore.
(getHeavyweightParent): Removed. Not needed anymore.
(getOffscreenBuffer): Fetch offscreen image from the
actual root component.
(paintDirtyRegions): Don't call commitRemainingBuffers().


/Roman
Index: javax/swing/RepaintManager.java
===
RCS file: /cvsroot/classpath/classpath/javax/swing/RepaintManager.java,v
retrieving revision 1.43
diff -u -1 -2 -r1.43 RepaintManager.java
--- javax/swing/RepaintManager.java	26 Jul 2006 21:16:51 -	1.43
+++ javax/swing/RepaintManager.java	17 Aug 2006 15:00:52 -
@@ -29,36 +29,36 @@
 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 javax.swing;
 
+import java.applet.Applet;
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Image;
 import java.awt.Rectangle;
 import java.awt.Window;
 import java.awt.image.VolatileImage;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
 
 /**
  * The repaint manager holds a set of dirty regions, invalid components,
  * and a double buffer surface.  The dirty regions and invalid components
  * are used to coalesce multiple revalidate() and repaint() calls in the
  * component tree into larger groups to be refreshed "all at once"; the
  * double buffer surface is used by root components to paint
  * themselves.
  *
  * See dirty parameter. This searches up the component
* hierarchy of dirty to find the highest parent that is also
* marked dirty and merges the dirty regions.
*
* @param dirtyRegions the dirty regions 
* @param dirty the component for which to find the repaint root
* @param roots the list to which new repaint roots get appended
@@ -634,148 +633,55 @@
   int proposedHeight)
   {
 Component root = SwingUtilities.getWindowAncestor(component);
 Image buffer = (Image) offscreenBuffers.get(root);
 if (buffer == null 
 || buffer.getWidth(null) < proposedWidth 
 || buffer.getHeight(null) < proposedHeight)
   {
 int width = Math.max(proposedWidth, root.getWidth());
 width = Math.min(doubleBufferMaximumSize.width, width);
 int height = Math.max(proposedHeight, root.getHeight());
 height = Math.min(doubleBufferMaximumSize.height, height);
-buffer = root.createImage(width, height);
+buffer = component.createImage(width, height);
 offscreenBuffers.put(root, buffer);
   }
 return buffer;
   }
 
   /**
-   * Blits the back buffer of the specified root component to the screen. If
-   * the RepaintManager is currently working on a paint request, the commit
-   * requests are queued up and committed at once when the paint request is
-   * done (by [EMAIL PROTECTED] #commitRemainingBuffers}). This is package private because
-   * it must get called by JComponent.
+   * Blits the back buffer of the specified root component to the screen.
+   * This is package private because it must get called by JComponent.
*
* @param comp the component to be painted
* @param area the area to paint on screen, in comp coordinates
*/
   void commitBuffer(Component comp, Rectangle area)
   {
-// Determine the component that we finally paint the buffer upon.
-// We need to paint on the nearest heavyweight component, so that Swing
-// hierarchies inside (non-window) heavyweights get painted correctly.
-// Otherwise we would end up blitting the backbuffer behind the heavyweight
-// which is wrong.
-Component root = getHeavyweightParent(comp);
-// FIXME: Optimize this.
-Rectangle rootRect = SwingUtilities.convertRectangle(comp, area, root);
-
-// We synchronize on 

[cp-patches] FYI: SwingUtilities.layoutCompoundLabel() fixes

2006-08-17 Thread Roman Kennke
I fixed the method SwingUtilities.layoutCompoundLabel() so that it 
passes the Intel and Mauve testsuite completely (except for some mauve 
tests that also fail on the JDK). Also, I have taken care to make it as 
efficient as possible, because that method is used in layouting and 
painting of a couple of component UIs.


Unfortunately, these UIs have been coded to match the wrong behaviour 
that we had in this method before. I needed to adjust all the UIs that 
use this method. While doing so, I changed these UIs to use cached 
Rectangles (that is in part the point of this method).


I also added the feature of trimming oversize strings, so that a 'very 
very very long String' will be trimmed to 'very very ve...' when it 
doesn't fit on the component.


Note that the JTabbedPane is broken now as it uses the 
SwingUtilities.layoutCompoundLabel() in the wrong way too. I didn't fix 
it up because I know that Robert is working on it and I want to talk to 
him first.


2006-08-17  Roman Kennke  <[EMAIL PROTECTED]>

* javax/swing/SwingUtilities.java
(clipString): New helper method for trimming strings.
(layoutCompoundLabelImpl): Fixed algorithm to conform
testsuites. Trim text if it's too long. Avoid creating
new Rectangles. Optimized for performance.
(layoutCompoundLabel): Use switch rather then if-else-chain.
* javax/swing/plaf/basic/BasicButtonUI.java
(viewR): New field.
(iconR): New field.
(textR): New field.
(paint): Reset and use cached rectangles. Only call paintIcon()
if icon is not null. Don't call paintButtonPressed() when
button is selected, only when it is both armed and pressed.
* javax/swing/plaf/basic/BasicGraphicsUtils.java
(getPreferredButtonSize): Reused cached rectangles rather
then creating new ones. Don't create new Rectangle via
Rectangle.union().
* javax/swing/plaf/basic/BasicLabelUI.java
(getPreferredSize): Correctly reset cached rectangles. Especially
the view rect must have a big size to give it room for layouting.
Short cut layout when text == null.
(paint): Correctly reset cached rectangles.
* javax/swing/plaf/basic/BasicMenuItemUI.java
(resetRectangles): New helper method.
(getPreferredMenuItemSize): Correctly reset the cached rectangles.
(paintMenuItem): Correctly reset the cached rectangles.
* javax/swing/plaf/basic/BasicRadioButtonUI.java
(getPreferredSize): Use cached Rectangle objects and initialize
them correctly.
(paint): Use cached Rectangle objects and initialize
them correctly.


/Roman
Index: javax/swing/SwingUtilities.java
===
RCS file: /cvsroot/classpath/classpath/javax/swing/SwingUtilities.java,v
retrieving revision 1.56
diff -u -1 -2 -r1.56 SwingUtilities.java
--- javax/swing/SwingUtilities.java	4 Aug 2006 11:09:11 -	1.56
+++ javax/swing/SwingUtilities.java	17 Aug 2006 14:44:56 -
@@ -31,25 +31,24 @@
 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 javax.swing;
 
 import java.applet.Applet;
 import java.awt.Component;
-import java.awt.ComponentOrientation;
 import java.awt.Container;
 import java.awt.FontMetrics;
 import java.awt.Frame;
 import java.awt.Graphics;
 import java.awt.Insets;
 import java.awt.KeyboardFocusManager;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Shape;
 import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.awt.event.InputEvent;
@@ -712,56 +711,53 @@
int verticalAlignment,
int horizontalAlignment, 
int verticalTextPosition,
int horizontalTextPosition, 
Rectangle viewR,
Rectangle iconR, 
Rectangle textR, 
int textIconGap)
   {
 
 // Fix up the orientation-based horizontal positions.
 
-if (horizontalTextPosition == LEADING)
-  {
-if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
-  horizontalTextPosition = RIGHT;
-else
-  horizontalTextPosition = LEFT;
-  }
-else if (horizontalTextPosition == TRAILING)
+boolean ltr = true;
+if (c != null && ! c.getComponentOrientation().isLeftToRight())
+  ltr = false;
+
+switch (horizont

[cp-patches] FYI: java.util.Calendar - some API doc additions

2006-08-17 Thread David Gilbert
This patch (committed) adds some details to the API docs regarding null arguments 
for a few methods that I happened to be looking at today:


2006-08-17  David Gilbert  <[EMAIL PROTECTED]>

* java/util/Calendar.java: API doc additions.

Regards,

Dave
Index: java/util/Calendar.java
===
RCS file: /sources/classpath/classpath/java/util/Calendar.java,v
retrieving revision 1.49
diff -u -r1.49 Calendar.java
--- java/util/Calendar.java 7 May 2006 22:49:49 -   1.49
+++ java/util/Calendar.java 17 Aug 2006 12:22:29 -
@@ -1,5 +1,6 @@
 /* Calendar.java --
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005  Free Software 
Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,  
+   Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -483,6 +484,8 @@
   /**
* Creates a calendar representing the actual time, using the default
* time zone and locale.
+   * 
+   * @return The new calendar.
*/
   public static synchronized Calendar getInstance()
   {
@@ -492,7 +495,12 @@
   /**
* Creates a calendar representing the actual time, using the given
* time zone and the default locale.
-   * @param zone a time zone.
+   * 
+   * @param zone a time zone (null not permitted).
+   * 
+   * @return The new calendar.
+   * 
+   * @throws NullPointerException if zone is null.
*/
   public static synchronized Calendar getInstance(TimeZone zone)
   {
@@ -502,7 +510,12 @@
   /**
* Creates a calendar representing the actual time, using the default
* time zone and the given locale.
-   * @param locale a locale.
+   * 
+   * @param locale a locale (null not permitted).
+   * 
+   * @return The new calendar.
+   * 
+   * @throws NullPointerException if locale is null.
*/
   public static synchronized Calendar getInstance(Locale locale)
   {
@@ -524,8 +537,14 @@
   /**
* Creates a calendar representing the actual time, using the given
* time zone and locale.
-   * @param zone a time zone.
-   * @param locale a locale.
+   * 
+   * @param zone a time zone (null not permitted).
+   * @param locale a locale (null not permitted).
+   * 
+   * @return The new calendar.
+   * 
+   * @throws NullPointerException if zone or locale
+   * is null.
*/
   public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
   {
@@ -617,6 +636,10 @@
   /**
* Sets this Calendar's time to the given Date.  All time fields
* are invalidated by this method.
+   * 
+   * @param date  the date (null not permitted).
+   * 
+   * @throws NullPointerException if date is null.
*/
   public final void setTime(Date date)
   {


Re: [cp-patches] FYI: Vector fixlet

2006-08-17 Thread Roman Kennke

Hi Paul,


Probably a dodgy test but I think this commit:

On Tue, 2006-08-15 at 11:44 +0200, Roman Kennke wrote:

2006-08-15  Roman Kennke  <[EMAIL PROTECTED]>

* java/util/Vector.java
(removeAll): Don't explicitly null-check here. The RI allows
null arguments when Vector is empty. In other cases we
implicitly throw an NPE.
(retainAll): Don't explicitly null-check here. The RI allows
null arguments when Vector is empty. In other cases we
implicitly throw an NPE.


caused the following mauve regression:

FAIL: java.util.Vector.AcuniaVectorTest

Just in case you hadn't spotted it,


Yes, but the JDK also fails this test, so I didn't worry about it.

/Roman



[cp-patches] FYI: DefaultButtonModel - expression simplification

2006-08-17 Thread Robert Schuster
Hi,
this small patch simplifies an expression.

ChangeLog:

2006-08-17  Robert Schuster  <[EMAIL PROTECTED]>

* javax/swing/DefaultButtonModel.java:
(setRollover): Simplified statement.


cya
Robert
Index: javax/swing/DefaultButtonModel.java
===
RCS file: /cvsroot/classpath/classpath/javax/swing/DefaultButtonModel.java,v
retrieving revision 1.29
diff -u -r1.29 DefaultButtonModel.java
--- javax/swing/DefaultButtonModel.java	16 Jun 2006 13:44:59 -	1.29
+++ javax/swing/DefaultButtonModel.java	17 Aug 2006 00:03:19 -
@@ -425,7 +425,7 @@
   public void setRollover(boolean r)
   {
 // if this call does not represent a CHANGE in state, then return
-if ((r && isRollover()) || (!r && !isRollover()))
+if (r == isRollover())
   return;
 
 // cannot set ROLLOVER property unless button is enabled


signature.asc
Description: OpenPGP digital signature


[cp-patches] FYI: RMI class loading patch

2006-08-17 Thread Jeroen Frijters
Hi,

I committed my RMI class loading patch.

Regards,
Jeroen

2006-08-17  Jeroen Frijters  <[EMAIL PROTECTED]>

* gnu/java/rmi/server/RMIClassLoaderImpl.java
(loadClass): Rewritten to use getClassLoader.
(loadProxyClass): Implemented.
(getClassLoader): Fixed support for null or empty codebase.
* gnu/java/rmi/server/RMIObjectInputStream.java
(resolveClass): Use user class loader as default class loader.
(resolveProxyClass): Delegate to RMIClassLoader.loadProxyClass.
* gnu/javax/rmi/CORBA/UtilDelegateImpl.java
(loadClass): Simplified and use user class loader instead of
context class loader as default.
* java/io/ObjectInputStream.java
(currentLoader): Use VMStackWalker.firstNonNullClassLoader().
* vm/reference/gnu/classpath/VMStackWalker.java
(firstNonNullClassLoader): New method.
* vm/reference/java/io/VMObjectInputStream.java
(loaderAction, currentClassLoader): Removed.
Index: gnu/java/rmi/server/RMIClassLoaderImpl.java
===
RCS file: 
/cvsroot/classpath/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java,v
retrieving revision 1.1
diff -u -r1.1 RMIClassLoaderImpl.java
--- gnu/java/rmi/server/RMIClassLoaderImpl.java 28 Sep 2005 19:51:31 -  
1.1
+++ gnu/java/rmi/server/RMIClassLoaderImpl.java 13 Aug 2006 11:22:24 -
@@ -1,5 +1,5 @@
 /* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,6 +38,7 @@
 
 package gnu.java.rmi.server;
 
+import java.lang.reflect.Proxy;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -186,6 +187,7 @@
   {
 defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, 
null,
defaultAnnotation);
+// XXX using getContextClassLoader here *cannot* be right
 cacheLoaders.put (new CacheKey (defaultAnnotation,
 
Thread.currentThread().getContextClassLoader()),
 defaultClassLoader);
@@ -216,47 +218,53 @@
  ClassLoader defaultLoader)
 throws MalformedURLException, ClassNotFoundException
   {
-ClassLoader loader;
-if (defaultLoader == null)
-  loader = Thread.currentThread().getContextClassLoader();
-else
-  loader = defaultLoader;
-
-//try context class loader first
 try 
   {
-return Class.forName(name, false, loader);
+if (defaultLoader != null)
+return Class.forName(name, false, defaultLoader);
   }
 catch (ClassNotFoundException e)
   {
-// class not found in the local classpath
+  }
+
+return Class.forName(name, false, getClassLoader(codeBase));
+  }
+
+  public Class loadProxyClass(String codeBase, String[] interfaces,
+  ClassLoader defaultLoader)
+  throws MalformedURLException, ClassNotFoundException
+  {
+Class clss[] = new Class[interfaces.length];
+
+for (int i = 0; i < interfaces.length; i++)
+  {
+clss[i] = loadClass(codeBase, interfaces[i], defaultLoader);
   }
 
-if (codeBase.length() == 0) //==""
+// Chain all class loaders (they may differ).
+ArrayList loaders = new ArrayList(clss.length);
+ClassLoader loader = null;
+for (int i = 0; i < clss.length; i++)
   {
-loader = defaultClassLoader;
+loader = clss[i].getClassLoader();
+if (! loaders.contains(loader))
+  {
+loaders.add(0, loader);
+  }
   }
-else
+if (loaders.size() > 1)
   {
-loader = getClassLoader(codeBase);
+loader = new CombinedClassLoader(loaders);
   }
 
-if (loader == null)
+try
   {
-//do not throw NullPointerException
-throw new ClassNotFoundException ("Could not find class (" + name +
-  ") at codebase (" + codeBase + ")");
+return Proxy.getProxyClass(loader, clss);
+  }
+catch (IllegalArgumentException e)
+  {
+throw new ClassNotFoundException(null, e);
   }
-
-return Class.forName(name, false, loader);
-  }
-
-  public Class loadProxyClass(String codeBase, String[] interfaces,
-  ClassLoader defaultLoader)
-  throws MalformedURLException, ClassNotFoundException
-  {
-// FIXME: Implement this.
-return null;
   }
 
   /**
@@ -272,6 +280,9 @@
   public ClassLoader getClassLoader(String codebase)
 throws MalformedURLException
   {
+if (codebase == null || codebase.length() == 0)
+  return Thread.currentThread().getContextClassLoader();
+
 ClassLoader loader;
 CacheKey loaderKey = new