Bug 22963 - custom-made CharsetProvider cannot be loaded
Summary: custom-made CharsetProvider cannot be loaded
Status: RESOLVED FIXED
Alias: None
Product: classpath
Classification: Unclassified
Component: classpath (show other bugs)
Version: unspecified
: P3 normal
Target Milestone: 0.19
Assignee: Tom Tromey
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-01 09:09 UTC by from-classpath
Modified: 2005-09-18 01:04 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-09-17 23:20:36


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description from-classpath 2005-06-01 09:09:53 UTC
I have a custom-made class that extends
   java.nio.charset.spi.CharsetProvider
whose name is written in
   META-INF/services/java.nio.charset.spi.CharsetProvider.

I have found two problems when the VM loads the custom-made
CharsetProvider.

(1) We can put blank lines, spaces, tabs and comments following
    '#' in META-INF/services/java.nio.charset.spi.CharsetProvider.
    But java.nio.charset.Charset does not ignore them.

(2) java.nio.charset.Charset tries to load the class using
    Class.forName(className), which means that the ClassLoader
    that loaded java.nio.charset.Charset is used.  Most likely,
    java.nio.charset.Charset is in the VM's bootstrap classpath,
    so the custom-made CharsetProvider must also be found somewhere
    in the VM's bootstrap classpath.  Just putting it in the
    usual classpath does not work.

And here is my proposed patch:

--- java/nio/charset/Charset.java.orig	Wed Jun  1 16:56:01 2005
+++ java/nio/charset/Charset.java	Wed Jun  1 17:28:43 2005
@@ -267,8 +267,29 @@
                     String s = rdr.readLine();
                     if (s == null)
 		      break;
+		    int i = -1, j = -1;
+		    for (int k = 0; k < s.length(); k++)
+		      {
+			char c = s.charAt(k);
+			if (c == ' ' || c == '	')
+			  continue;
+			if (c == '#')
+			  break;
+			i = k;
+			break;
+		      }
+		    if (i < 0)
+			continue;
+		    for (j = i + 1; j < s.length(); j++)
+		      {
+			char c = s.charAt(j);
+			if (c == ' ' || c == '	' || c == '#')
+			  break;
+		      }
+		    s = s.substring(i, j); 
                     CharsetProvider p =
-		      (CharsetProvider) ((Class.forName(s)).newInstance());
+		      (CharsetProvider) ((Class.forName(s, true,
+			 ClassLoader.getSystemClassLoader())).newInstance());
                     set.add(p);
                   }
                }
Comment 1 from-classpath 2005-06-01 23:16:30 UTC
> + (CharsetProvider) ((Class.forName(s, true,
> + ClassLoader.getSystemClassLoader())).newInstance());


This must be Thread.currentThread().getContextClassLoader()
instead of ClassLoader.getSystemClassLoader().

Comment 2 from-classpath 2005-06-05 22:25:25 UTC
This is the patch applied in Kaffe.

ChangeLog:

2005-06-05  Ito Kazumitsu  <kaz@maczuka.gcd.org>

	* java/nio/charset/Charset.java
	(providers2): Allow spaces and comments in
	META-INF/services/java.nio.charset.spi.CharsetProvider.
	Load the provider using the context class loader.

--- java/nio/charset/Charset.java.orig	Wed May 18 06:28:40 2005
+++ java/nio/charset/Charset.java	Sun Jun  5 10:52:25 2005
@@ -267,8 +267,29 @@
                     String s = rdr.readLine();
                     if (s == null)
 		      break;
+		    int i = -1, j = -1;
+		    for (int k = 0; k < s.length(); k++)
+		      {
+			char c = s.charAt(k);
+			if (c == ' ' || c == '\t')
+			  continue;
+			if (c == '#')
+			  break;
+			i = k;
+			break;
+		      }
+		    if (i < 0)
+			continue;
+		    for (j = i + 1; j < s.length(); j++)
+		      {
+			char c = s.charAt(j);
+			if (c == ' ' || c == '\t' || c == '#')
+			  break;
+		      }
+		    s = s.substring(i, j);
                     CharsetProvider p =
-		      (CharsetProvider) ((Class.forName(s)).newInstance());
+		      (CharsetProvider) ((Class.forName(s, true,
+			 Thread.currentThread().getContextClassLoader())).newInstance());
                     set.add(p);
                   }
                }

Comment 3 from-classpath 2005-06-06 00:29:30 UTC
Thanks, I'll check this into Classpath.
Comment 4 Andrew Pinski 2005-07-26 16:02:44 UTC
Confirmed.
Comment 5 Tom Tromey 2005-07-27 02:52:34 UTC
Actually I think Charset should use the ServiceFactory class for this.
And, I don't see why the context class loader should be used -- it seems
to me that the system class loader is a reasonable choice, but that,
in addition, we should write a test case to see which is correct.

Comment 6 Ito Kazumitsu 2005-07-27 21:39:36 UTC
> And, I don't see why the context class loader should be used -- it seems > to me that the system class loader is a reasonable choice, but that, > in addition, we should write a test case to see which is correct.  I think the context class loader should be used because    (1) Sun's API document of java.nio.charset.spi.CharsetProvider says:  	Charset providers are looked up via the current thread's 	context class loader.    (2) If charset providers are to be loaded via the system class loader,       the user may have to specify -bootclasspath or something.       Just putting the custom-made provider somewhere in the classpath       may not work.  
Comment 7 Tom Tromey 2005-09-17 23:20:36 UTC
I have a patch which uses ServiceFactory and the context
class loader.
Comment 8 cvs-commit@developer.classpath.org 2005-09-18 01:00:27 UTC
Subject: Bug 22963

CVSROOT:	/cvsroot/classpath
Module name:	classpath
Branch: 	
Changes by:	Tom Tromey <tromey@savannah.gnu.org>	05/09/18 00:56:22

Modified files:
	.              : ChangeLog 
	java/nio/charset: Charset.java 

Log message:
	PR classpath/22963:
	* java/nio/charset/Charset.java (forName): Javadoc fix.
	(providers2): Use ServiceFactory.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/classpath/classpath/ChangeLog.diff?tr1=1.4843&tr2=1.4844&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/classpath/classpath/java/nio/charset/Charset.java.diff?tr1=1.25&tr2=1.26&r1=text&r2=text




Comment 9 Tom Tromey 2005-09-18 01:04:47 UTC
Fix checked in