[kaffe] Adding a class to the library?

Benja Fallenstein b.fallenstein@gmx.de
Tue May 13 05:24:01 2003


This is a multi-part message in MIME format.
--------------090106070403060209030104
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit


Hallo Dalibor,

Dalibor Topic wrote:
> there is a bug in kaffe's libraries/javalib/Makefile.am so that it creates a
> rt.jar file even if the class library compilation step doesn't succeed, leading
> to missing classes in rt.jar. A fix for that one would be most welcome.

Ah, thanks! Unfortunately I don't understand that stuff well enough to 
find the bug. But from the below--

> java/security/MessageDigest.java:137: error:Cannot find constructor
> "MessageDigest" with matching parameters [JLS 15.12]
> java/security/MessageDigest.java:154: error:Cannot find method
> "UnsupportedOperationException(java.lang.String)"

I found a workaround: grepping make's output for 'error'.

Attached are the now working patch to MessageDigest, plus a short FAQ 
item you might want to put in FAQ.classlibrary-compile :-)

Thanks,
- Benja

--------------090106070403060209030104
Content-Type: text/plain;
 name="digest.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="digest.diff"

Index: libraries/javalib/java/security/MessageDigest.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/security/MessageDigest.java,v
retrieving revision 1.4
diff -u -r1.4 MessageDigest.java
--- libraries/javalib/java/security/MessageDigest.java	20 Feb 2003 13:52:09 -0000	1.4
+++ libraries/javalib/java/security/MessageDigest.java	13 May 2003 12:15:28 -0000
@@ -19,16 +19,23 @@
 
 // Note: it is a historical screwup that this class extends MessageDigestSpi.
 // It should not but does. Unfortunately, MessageDigestSpi is abstract, and
-// this class inherits that abstractness. That is why we must be able to
-// cast the engine we get from the provider to a MessageDigest object instead
-// of a MessageDigestSpi object (see ***note below). Normally this class
-// would keep an instance of MessageDigestSpi in a private field, but instead
-// 'this' is that instance, so we don't need a separate field for it.
+// this class inherits that abstractness. As a consequence, a number of classes
+// that should extend MessageDigestSpi extend MessageDigest instead.
+
+// On the other hand, *some* classes that should extend MessageDigestSpi
+// *do* extend it. We need to handle that too.
+
+// Therefore, this class proxies all calls to its engine-- but the engine is,
+// by default, 'this'. When we need to construct a MessageDigest object
+// wrapping a MessageDigestSpi object, we use a concrete subclass of
+// MessageDigest, NonSpiMessageDigest, and change its 'engine' field
+// to the actual MessageDigestSpi. Calling engine methods on a
+// NonSpiMessageDigest object throws an UnsupportedOperationException.
 
 public abstract class MessageDigest extends MessageDigestSpi {
 	private static final String ENGINE_CLASS = "MessageDigest";
 	private final String algorithm;
-   /**	private MessageDigestSpi engine; **/
+        private MessageDigestSpi engine = this;
 	private Provider provider;
 
 	protected MessageDigest(String algorithm) {
@@ -49,9 +56,15 @@
 	}
 
 	private static MessageDigest getInstance(Security.Engine e) {
-		MessageDigest md = (MessageDigest)e.getEngine(); // ***note
-		// should be: md = new MessageDigest(e.algorithm);
-	  /**	md.engine = (MessageDigestSpi)e.engine;	  **/
+		MessageDigest md;
+		Object o = e.getEngine();
+		if(o instanceof MessageDigest) {
+			md = (MessageDigest)o;
+		} else {
+			md = new NonSpiMessageDigest(e.algorithm);
+			md.engine = (MessageDigestSpi)o;
+		}
+
 		md.provider = e.getProvider();
 		return md;
 	}
@@ -61,11 +74,11 @@
 	}
 
 	public void update(byte input) {
-		/*engine.*/engineUpdate(input);
+		engine.engineUpdate(input);
 	}
 
 	public void update(byte[] input, int offset, int len) {
-		/*engine.*/engineUpdate(input, offset, len);
+		engine.engineUpdate(input, offset, len);
 	}
 
 	public void update(byte[] input) {
@@ -73,14 +86,14 @@
 	}
 
 	public byte[] digest() {
-		byte[] rtn = /*engine.*/engineDigest();
-		/*engine.*/engineReset();
+		byte[] rtn = engine.engineDigest();
+		engine.engineReset();
 		return rtn;
 	}
 
 	public int digest(byte[] buf, int offset, int len)
 			throws DigestException {
-		int digestLen = /*engine.*/engineGetDigestLength();
+		int digestLen = engine.engineGetDigestLength();
 		if (len < digestLen) {
 			throw new DigestException("buf.length < " + digestLen);
 		}
@@ -103,7 +116,7 @@
 	}
 
 	public void reset() {
-		/*engine.*/engineReset();
+		engine.engineReset();
 	}
 
 	public final String getAlgorithm() {
@@ -111,11 +124,40 @@
 	}
 
 	public final int getDigestLength() {
-		return /*engine.*/engineGetDigestLength();
+		return engine.engineGetDigestLength();
 	}
 
 	public Object clone() throws CloneNotSupportedException {
 		return super.clone();
+	}
+
+	private static String NONSPI_MSG =
+		"This MessageDigest is not a MessageDigestSpi. "+
+		"MessageDigestSpi methods should not be used "+
+		"on MessageDigest objects."; 
+
+	private static class NonSpiMessageDigest extends MessageDigest {
+		protected NonSpiMessageDigest(String algorithm) {
+			super(algorithm);
+		}
+		protected int engineGetDigestLength() {
+			throw new UnsupportedOperationException(NONSPI_MSG);
+		}
+		protected void engineUpdate(byte input) {
+			throw new UnsupportedOperationException(NONSPI_MSG);
+		}
+		protected void engineUpdate(byte[] input, int offset, int len) {
+			throw new UnsupportedOperationException(NONSPI_MSG);
+		}
+		protected byte[] engineDigest() {
+			throw new UnsupportedOperationException(NONSPI_MSG);
+		}
+		protected int engineDigest(byte[] buf, int offset, int len) {
+			throw new UnsupportedOperationException(NONSPI_MSG);
+		}
+		protected void engineReset() {
+			throw new UnsupportedOperationException(NONSPI_MSG);
+		}
 	}
 }
 

--------------090106070403060209030104
Content-Type: text/plain;
 name="faq.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="faq.diff"

Index: FAQ/FAQ.classlibrary-compile
===================================================================
RCS file: /cvs/kaffe/kaffe/FAQ/FAQ.classlibrary-compile,v
retrieving revision 1.11
diff -u -r1.11 FAQ.classlibrary-compile
--- FAQ/FAQ.classlibrary-compile	23 Apr 2003 01:17:56 -0000	1.11
+++ FAQ/FAQ.classlibrary-compile	13 May 2003 12:20:45 -0000
@@ -25,6 +25,16 @@
 If you want to rebuild not only Klasses.jar, but also the jar-files of
 Kaffe extensions, type "make CLASSDIRS=all Klasses".
 
+Why don't I get a working rt.jar even though the 'make' went fine?
+------------------------------------------------------------------
+
+There is a bug in kaffe's libraries/javalib/Makefile.am so that it
+creates a rt.jar file even if the class library compilation step
+doesn't succeed, leading to missing classes in rt.jar. A fix for that
+one would be most welcome.
+
+As a workaround, you can grep the output of 'make' for "error".
+
 How do I set the compiler?
 --------------------------
 

--------------090106070403060209030104--