[cp-patches] Re: Ping: Fix DiffieHellmanImpl.java
Sorry I forgot about this. On Sep 4, 2007, at 11:17 AM, Andrew Haley wrote: From: Andrew Haley [EMAIL PROTECTED] Date: August 3, 2007 10:19:07 AM PDT To: Casey Marshall [EMAIL PROTECTED], classpath-patches@gnu.org Cc: Lillian Angel [EMAIL PROTECTED] Subject: Fix DiffieHellmanImpl.java I came across a problem with GNU Crypto that causes Diffie-Hellman key exchange to fail when running on IcedTea. We're doing what looks to me like an unnecessary check in DiffieHellmanImpl.engineDoPhase() which can fail in some circumstances, and this is triggered when running in IcedTea. The code runs correctly on Sun's Java 1.7, not on the IcedTea version of Java 1.7, which uses GNU Crypto. I think this is OK. I'm sure there are valid instances where the l values won't match. With IcedTea and Classpath we get: Exception in thread main java.security.InvalidKeyException: Incompatible key at gnu.javax.crypto.jce.DiffieHellmanImpl.engineDoPhase (DiffieHellmanImpl.java:99) at javax.crypto.KeyAgreement.doPhase(KeyAgreement.java:224) at Tt.main(Tt.java:35) Here's my patch:
Re: [cp-patches] Re: RFC: native/jni/java-nio/gnu_java_nio_VMChannel.c
On Jun 27, 2007, at 3:27 PM, Ito Kazumitsu wrote: Casey Marshall wrote. I meant the curly braces, the #if..#endif is appropriate. The source code now looks like this. What is the preferred way of writing this? Sorry, I'm just stupid :-) I read the patch wrong; it's good as-is. Thanks.
Re: [cp-patches] RFC: native/jni/java-nio/gnu_java_nio_VMChannel.c
On Jun 20, 2007, at 3:32 PM, Ito Kazumitsu wrote: Hi, Hi Ito, FreeBSD needs both ioctl and fstat, The former for character devices and the latter for files. This looks fine to me; I admit I haven't tried it, but nothing obviously wrong jumps out at me. Thanks. ChangeLog: 2007-06-21 Ito Kazumitsu [EMAIL PROTECTED] Fixes bug #30377 * native/jni/java-nio/gnu_java_nio_VMChannel.c (Java_gnu_java_nio_VMChannel_available): Retry using fstat if ioctl fails with ENOTTY. Index: classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c === RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/ gnu_java_nio_VMChannel.c,v retrieving revision 1.19 diff -u -r1.19 gnu_java_nio_VMChannel.c --- classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c 30 May 2007 09:56:57 - 1.19 +++ classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c 20 Jun 2007 22:22:14 - @@ -1586,9 +1586,30 @@ jint avail = 0; +#if defined(ENOTTY) defined(HAVE_FSTAT) + struct stat statBuffer; + off_t n; +#endif + /* NIODBG(fd: %d, fd); */ if (ioctl (fd, FIONREAD, avail) == -1) -JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); +{ Not sure why you have this block... +#if defined(ENOTTY) defined(HAVE_FSTAT) + if (errno == ENOTTY) +{ + if ((fstat (fd, statBuffer) == 0) S_ISREG (statBuffer.st_mode)) +{ + n = lseek (fd, 0, SEEK_CUR); + if (n != -1) +{ + avail = statBuffer.st_size - n; + return avail; +} +} +} +#endif + JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); ...surrounding it, though. +} /* NIODBG(avail: %d, avail); */ return avail;
Re: [cp-patches] FYI Only truncate a file on append and write-only (from FileOutputStream)
On May 30, 2007, at 4:21 AM, Steve Blackburn wrote: Is there any particular reason for having native implementations of open() in both gnu_java_nio_VMChannel.c and gnu_java_nio_FileChannelImpl.c? Aside from the bug in VMChannel, this duplication of open seemed to be the cause of the problem I saw. gnu_java_nio_FileChannelImpl.c was removed from CVS, six months ago. Refactoring of FileChannelImpl.java lead to an (unintended?) switch between open() implementations and exposed the bug. I couldn't work out why there were two implementations in the first place. The point of the refactoring was to move all of the native methods from FileChannelImpl into the the VM/platform layer, VMChannel. It was completely deliberate to switch to VMChannel -- that was the point. As for the bug, oops (I think it may have been my fault).
Re: [cp-patches] Gnu classpath permission patch ?
On May 25, 2007, at 12:37 AM, Pierre Parrend wrote: Hello, thanks for the tip, to tell the Classes to use the right policy reader is usefull. However, I now get a ugly NullPointerException in policy reading, it seems that the given reader has problem reading the name of the ProtectionDomain: Hmm, no, this looks more like a problem with recursive permission checks; that is, something needs to have a permission checked while it's checking a permission. It also looks like Classpath will eventually deny the permission your code is requesting. This is a little odd, because it looks like Classpath internal code is being denied a permission. That's wrong; library code should be able to do what it pleases. This feels like a regression. What version of Classpath and jamvm are you using? Thanks. java.lang.ExceptionInInitializerError at gnu.java.security.x509.X509Certificate.toString (X509Certificate.java:455) at java.lang.StringBuffer.append(StringBuffer.java:348) at java.security.CodeSource.toString(CodeSource.java:269) at java.lang.StringBuffer.append(StringBuffer.java:348) at java.security.ProtectionDomain.toString(ProtectionDomain.java: 212) at java.lang.StringBuffer.append(StringBuffer.java:348) at java.security.AccessControlContext.checkPermission (AccessControlContext.java:157) at java.security.AccessController.checkPermission (AccessController.java:76) at java.lang.SecurityManager.checkPermission (SecurityManager.java:356) at java.lang.SecurityManager.checkPropertyAccess (SecurityManager.java:820) at java.lang.System.getProperty(System.java:397) at org.apache.felix.main.Main.clinit(Main.java:66) Caused by: java.lang.NullPointerException at java.io.PrintWriter.println(PrintWriter.java:395) at java.io.PrintWriter.println(PrintWriter.java:523) at gnu.java.security.x509.X509Certificate.toString (X509Certificate.java:456) at java.lang.StringBuffer.append(StringBuffer.java:348) at java.security.CodeSource.toString(CodeSource.java:269) at java.lang.StringBuffer.append(StringBuffer.java:348) at java.security.ProtectionDomain.toString(ProtectionDomain.java: 212) at java.lang.StringBuffer.append(StringBuffer.java:348) at java.security.AccessControlContext.checkPermission (AccessControlContext.java:157) at java.security.AccessController.checkPermission (AccessController.java:76) at java.lang.SecurityManager.checkPermission (SecurityManager.java:356) at java.lang.SecurityManager.checkPropertyAccess (SecurityManager.java:820) at java.lang.System.getProperty(System.java:418) at java.io.PrintWriter.clinit(PrintWriter.java:381) at gnu.java.security.x509.X509Certificate.toString (X509Certificate.java:455) Quoting Casey Marshall [EMAIL PROTECTED]: On May 24, 2007, at 1:58 PM, Pierre Parrend wrote: Hello, for instance, I have the following command: jamvm -Djava.security.manager -Djava.security.policy=conf/ java.policy -cp bin/felix.jar: org.apache.felix.main.Main (jamvm uses the Gnu classpath, with default configuration) with following conf/java.policy file: grant codeBase /code/osgi-projects/sfelix/sfelix0.2.2/main/- { permission java.io.FilePermission /home/pierre/.felix/ testSF, read; permission java.lang.RuntimePermission exitVM; }; which gives me following error: Error creating bundle cache: permission (java.io.FilePermission /home/pierre/.felix/testSF read) not granted: no protection domains Could not create framework: java.security.AccessControlException: permission (java.lang.RuntimePermission exitVM ) not granted: no protection domains java.security.AccessControlException: permission (java.lang.RuntimePermission exitVM ) not granted: no protection domains at java.security.AccessControlContext.checkPermission (AccessControlContext.java:149) at java.security.AccessController.checkPermission (AccessController.java:76) at java.lang.SecurityManager.checkPermission (SecurityManager.java:356) at java.lang.SecurityManager.checkExit(SecurityManager.java:475) at java.lang.Runtime.exit(Runtime.java:171) at java.lang.System.exit(System.java:506) at org.apache.felix.framework.util.SecureAction$Actions.run (SecureAction.java:843) at java.security.AccessController.doPrivileged (AccessController.java:195) at org.apache.felix.framework.util.SecureAction.exit (SecureAction.java:624) at org.apache.felix.framework.Felix.start(Felix.java:276) at org.apache.felix.main.Main.main(Main.java:208) (executed platform is the Felix OSGi implementation, which work well without the security set) One problem here is that Classpath still unfortunately uses a bogus DefaultPolicy class for its policy, not the one that reads policy files. You can force using the policy file reader by adding the option: -Dpolicy.provider=gnu.java.security.PolicyFile ...I don't know why the default policy would reject the permission checks
Re: [cp-patches] Gnu classpath permission patch ?
On May 24, 2007, at 11:03 AM, Pierre Parrend wrote: Hello, in a different test context, it works. But I do not manage to get the java.policy file read, so my code aborts very soon. Does someone knows whether the supported syntax of this file is identical as in the sun jvm ? It seems that jamvm+Gnu Classpath has some difficulties in reading the properties that are defined (such a - Djava.security.policy). Any idea ? We do have a Policy implementation that reads Sun-style policy files, but we don't know if it is 100% compatible. If there is something we don't correctly support, I'd encourage you to file a bug report. We can't offer any more help unless you can be more specific about what error you are running into.
Re: [cp-patches] Gnu classpath permission patch ?
On May 24, 2007, at 1:58 PM, Pierre Parrend wrote: Hello, for instance, I have the following command: jamvm -Djava.security.manager -Djava.security.policy=conf/ java.policy -cp bin/felix.jar: org.apache.felix.main.Main (jamvm uses the Gnu classpath, with default configuration) with following conf/java.policy file: grant codeBase /code/osgi-projects/sfelix/sfelix0.2.2/main/- { permission java.io.FilePermission /home/pierre/.felix/ testSF, read; permission java.lang.RuntimePermission exitVM; }; which gives me following error: Error creating bundle cache: permission (java.io.FilePermission /home/pierre/.felix/testSF read) not granted: no protection domains Could not create framework: java.security.AccessControlException: permission (java.lang.RuntimePermission exitVM ) not granted: no protection domains java.security.AccessControlException: permission (java.lang.RuntimePermission exitVM ) not granted: no protection domains at java.security.AccessControlContext.checkPermission (AccessControlContext.java:149) at java.security.AccessController.checkPermission (AccessController.java:76) at java.lang.SecurityManager.checkPermission (SecurityManager.java:356) at java.lang.SecurityManager.checkExit(SecurityManager.java:475) at java.lang.Runtime.exit(Runtime.java:171) at java.lang.System.exit(System.java:506) at org.apache.felix.framework.util.SecureAction$Actions.run (SecureAction.java:843) at java.security.AccessController.doPrivileged (AccessController.java:195) at org.apache.felix.framework.util.SecureAction.exit (SecureAction.java:624) at org.apache.felix.framework.Felix.start(Felix.java:276) at org.apache.felix.main.Main.main(Main.java:208) (executed platform is the Felix OSGi implementation, which work well without the security set) One problem here is that Classpath still unfortunately uses a bogus DefaultPolicy class for its policy, not the one that reads policy files. You can force using the policy file reader by adding the option: -Dpolicy.provider=gnu.java.security.PolicyFile ...I don't know why the default policy would reject the permission checks, though, since (AFAIK) the default policy grants AllPermission.
[cp-patches] FYI: fix keyUsage bit checking
Our SSL client implementation was just passing the certificate to the RSA cipher, in the RSA key exchange. This implicitly checks the `dataEncipherment' bit of the certificate's keyUsage field, which isn't correct. The correct test is for the `keyEncipherment' bit. 2007-03-22 Casey Marshall [EMAIL PROTECTED] * gnu/javax/net/ssl/provider/ClientHandshake.java (RSAGen.implRun): check keyEncipherment bit of the certificate, and just pass the public key to the cipher. Committed. ssl-keyusage.patch Description: Binary data
[cp-patches] RFC: exceptions with no string constructor
I'm still testing this. This patch adds a JCL_ThrowExceptionNoMessage function, which invokes the void constructor of the given class, There are also a couple of issues in general in jcl.c. One is that in JCL_ThrowException, we throw a ClassNotFoundException if the specified exception class can't be found. There are two issues: 1. We don't return after throwing that exception, meaning we'll continue on and call ThrowNew again with a NULL class argument. 2. ClassNotFoundException is a checked exception, but very likely the native method we are in does not declare that it throws this. Could this be trouble brewing? Also, in JCL_malloc and JCL_realloc we throw OutOfMemoryExceptions if the native calls return NULL. It doesn't seem like this will work (though, if there is an explanation of why it will always work, I'll listen), so I've also modified this to allocate a static OutOfMemoryException on load, and these methods now throw that instance. 2007-02-02 Casey Marshall [EMAIL PROTECTED] * native/jni/classpath/jcl.c (OOM_obj): new static variable. (JNI_OnLoad): initialize `OOM_obj'. (JCL_ThrowException): return after throwing class not found exception. (JCL_ThrowExceptionNoMessage): new function. (JCL_malloc, JCL_realloc): throw `OOM_obj'. * native/jni/classpath/jni.h: include assert.h. (JCL_ThrowExceptionNoMessage): new function. * native/jni/java-nio/gnu_java_nio_VMChannel.c (Java_gnu_java_nio_VMChannel_read__ILjava_nio_ByteBuffer_2): don't throw NonReadableChannelException with a message. (Java_gnu_java_nio_VMChannel_readScattering): likewise. (Java_gnu_java_nio_VMChannel_writeGathering): don't throw NonWritableChannelException with a message. jcl-excep.patch Description: Binary data
Re: [cp-patches] RFC: exceptions with no string constructor
On Feb 2, 2007, at 9:55 PM, Jeroen Frijters wrote: Casey Marshall wrote: Also, in JCL_malloc and JCL_realloc we throw OutOfMemoryExceptions if the native calls return NULL. It doesn't seem like this will work (though, if there is an explanation of why it will always work, I'll listen), so I've also modified this to allocate a static OutOfMemoryException on load, and these methods now throw that instance. That's a good idea, but there's a bug in the implementation: +(*env)-NewGlobalRef (env, OOM_obj); That's not how NewGlobalRef works, it returns a new global ref, it doesn't modify the passed in ref. Yes indeed! Thanks for mentioning this.
[cp-patches] FYI: CipherOutputStream null check
I'm checking this in. It uses the suggested fix for Cipher implementations that may return `null', at the end of PR 24191. 2007-01-31 Casey Marshall [EMAIL PROTECTED] Fixes PR classpath/24191. Fix suggested by Rafael Teixeira [EMAIL PROTECTED]. * javax/crypto/CipherOutputStream.java (write): check return value of `update' for null. Cheers. coos.patch Description: Binary data
[cp-patches] FYI: consolidate Base-64 implementations
I'm checking this in. This removes two of the four Base-64 classes we have in Classpath (the last one is stream-based, so I'm not going to muck with it just yet) and updates the code to use the one implementation everywhere. I'm using the version that I wrote (since I volunteered to do this, I assumed veto power over which version to use ;-), which was in gnu.javax.net.ssl. I've moved that class to gnu.java.util.Base64, so if you have Base-64 encoding needs, use that one from now on! 2007-01-31 Casey Marshall [EMAIL PROTECTED] * gnu/javax/net/ssl/Base64.java: move to `gnu/java/util/Base64.java.' * gnu/javax/net/ssl/PrivateCredentials.java: clean up unused imports. (add): use `gnu.java.util.Base64.' * gnu/java/net/protocol/http/Request.java (authenticate): use `gnu.java.util.Base64.' * tools/gnu/classpath/tools/jarsigner/HashUtils.java (hashStream): likewise. * tools/gnu/classpath/tools/keytool/CertReqCmd.java (start): likewise. * tools/gnu/classpath/tools/keytool/ExportCmd.java (start): likewise. * tools/gnu/classpath/tools/keytool/ListCmd.java (printRFC1421): likewise. * gnu/java/net/Base64.java: removed. * gnu/java/security/util/Base64.java: removed. Cheers. base64.patch Description: Binary data
Re: [cp-patches] java.util.Arrays fix
On Dec 13, 2006, at 12:56 AM, Marco Trudel wrote: Hey guys java.util.Arrays.binarySearch(Object[] a, Object key, Comparator c) exchanges a[i] and key, this can lead to ClassCastExceptions as shown in ComparatorTest.java. Arrays.patch fixes it. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30061
Re: [cp-patches] java.util.Arrays fix
On Dec 13, 2006, at 12:21 PM, David Daney wrote: Casey Marshall wrote: On Dec 13, 2006, at 12:56 AM, Marco Trudel wrote: Hey guys java.util.Arrays.binarySearch(Object[] a, Object key, Comparator c) exchanges a[i] and key, this can lead to ClassCastExceptions as shown in ComparatorTest.java. Arrays.patch fixes it. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30061 This exact problem bit me once. I developed code on the RI that inadvertently had a comparator that depended on the order of the arguments. I freely admit that my code was incorrect, but it did take me a while to figure out what was happening. I feel that if there is no performance penalty, then we should follow the behavior of the RI. I agree, since we have a patch. As long as it tests out OK, I'm not opposed to including it. In general I really urge against going out of our way to support behavior like this.
Re: [cp-patches] java.util.Arrays fix
On Dec 13, 2006, at 1:28 PM, Marco Trudel wrote: David Daney wrote: Casey Marshall wrote: In general I really urge against going out of our way to support behavior like this. Can you explain that further? You're against changes that - keep the specification as correct as they were before - will adapt classpath to the RI behavior - will prevent users from running into problems - restore old classpath behavior (regression fix) - have no negative side effects whatsoever Sorry if that seems to be a mean summary. This are just the points I'm seeing and I'm actually really surprised about the number and kind of reactions to that patch or that the mentioned bugreport has been closed as invalid. It is not a bug. 'Nuff said. I was replying to David, not to you. I would have assumed that someone says: Hey great, this only fixes problems and doesn't do anything bad. Let's commit it. Huh? Didn't I say that? My reply (which you trimmed away) said this: I agree, since we have a patch. As long as it tests out OK, I'm not opposed to including it. So as I said, I don't mean to offend you, I just can't follow why we wouldn't follow the RI when we still fulfill the specifications. I did say that I was against *going out of our way* to adhere to the precise behavior of the RI, when neither the spec nor the algorithms used require it. It's fine if you want to go looking for things like this, and writing fixes for them. These are not a bugs, though, and are not a priority. To be blunt about it, I don't care if you waste your time doing this, but I am not going to. I changed my mind! As a matter of principle, since I had to fix my code, everyone should have to suffer in the same manner, as their penalty for disobeying the mandates of the specification! :) Whaaat? David! I really hope - for the sake of humanity - that you're joking. Ah right, there's a :) at the end. I was so shocked from that statement that I missed it first... In this case, the Comparator is still wrong. It may work now with Classpath's binarySearch, but it is *in general* broken. If it gets used with some other algorithm, it may not work. HIDING BUGS IN CODE IS BAD.
[cp-patches] Re: RFC: Socket VM interface
On Dec 12, 2006, at 2:40 AM, Roman Kennke wrote: Hi there, I am not happy with the current situation wrt to the Socket related VM interface. AFAICS, we have three layers of abstraction here: - On API level we have the Socket/SocketImpl/SocketImplFactory stuff. - Below this we have PlainSocketImpl and VMPlainSocketImpl et al. - On the native side there is some kind of target layer too. At least one of these layers seems superfluous. The VMSocketImpl class seems to mostly map the methods from the SocketImpl class again. I'd like to see the native target layer go away. I think the minimum required to support user threads and blocking calls (like what we do in NIO) should suffice. Are there any objections to boiling down the VM interface to something like: class VMSockets { SocketImplFactory getSocketImplFactory(); DatagramSocketImplFactory getDatagramSocketImplFactory(); } I think I see where you're going with this, and I agree that it would be cleaner. The line where VMs need to take over, and where the reference implementation will suffice, is a little blurry at the moment. Defining it better should help out. Of course, comments on how well this works for VM implementors who can't use the POSIXy RI would be well appreciated here. Thanks.
Re: [cp-patches] FYI: Use exception chaining in javax.net.ssl.SSLSocketFactory.getDefault()
On Dec 11, 2006, at 8:37 AM, Jeroen Frijters wrote: David Daney wrote: Jeroen Frijters wrote: throw new RuntimeException(error instantiating default socket factory: - + ex.toString()); That sounds more like an InternalError than the super-generic RuntimeException. Possibly. I don't know enough about this stuff to tell. I have, however, since discovered that the current code is wrong. When the factory is not properly configured it is supposed to return a factory that throws exceptions upon invocation of the factory methods, not at this stage. Really? That seems like worse behavior than just giving up when trying to create the factory. Just delaying exceptions like that seems like it will just hide bugs, instead of forcing you to deal with them up front. ...and yes, looking at the JavaDoc for 1.5 after writing that, they do say that it returns an inoperative factory on error. This makes no sense to me, but if that's what the RI does, then we should do it, too. I've got a patch (attached), but I'm going on vacation tomorrow and don't have time to properly test it and check it in, but if someone would like to do so, that would be great. I'll look at this, unless someone else wants to volunteer. Thanks.
Re: [cp-patches] Fix interrupted read/writes
On Dec 6, 2006, at 4:01 AM, Andrew Haley wrote: Casey Marshall writes: On Dec 5, 2006, at 2:52 AM, Andrew Haley wrote: The cpnio functions are (should be) trivial and inlined. What more is needed? Now, is VMChannel supposed to be POSIX-specific or not? If it is Yes, it is. supposed to be POSIX-specific, and there seem to be an awful lot of POSIXisms in there, why is it using cpio_connect() instead of simply connect(2)? I guessed that cpio_connect() was supposed to be a platform-independent abstraction on a syscall, but it isn't being used to do that: VMChannel.c isn't platform-independent. So cpio_connect() is useless, isn't it? No. This was trying to address the issues VM implementors had when it comes to user-space threads: syscalls that we use that can block indefinitely are wrapped in an easy-to-replace implementation, but otherwise the code assumes a POSIXy system. We went through this before. It seems that I didn't, anyway. Some of us may have discussed some of this on IRC/off list. I don't remember. I thought we had enough of a consensus that POSIX was a good enough abstraction for our reference implementation of the native code, as long as we left hooks like this in place for VMs when it comes to blocking IO calls. You'll notice that we don't do this for other functions that (according to the documentation) won't block. OH, OK. You are quite right: there is an explanation of this in javanio.h. So let me understand: this is to support a user-space threads package that requires special handling of blocking syscalls, perhaps one that doesn't provide wrappers for connect() _et al_. Yup. I seem to recall e.g. JikesRVM doing some LD_PRELOAD hackery to intercept blocking system calls. This should make that unnecessary, since all they need to do now is provide a different version of the cpnio_* functions. I would have preferred to simply omit the cpnio_* bits in the NIO changes I made, but a sufficient number of people did complain that this would not work well for green threaded VMs. And although these functions don't look like they will be inlined, they will because CPNIO_EXPORT is #defined static inline and javanio.c is #included by javanio.h. Yeah. Maybe the macro name isn't great, but in Classpath's version, it should be defined to inline those functions, since they're trivial. If some VM needed a more complicated implementation, they can #define CPNIO_EXPORT to be empty. Thanks.
Re: [cp-patches] [generics] Code-cleanup: remove unused imports
On Dec 6, 2006, at 2:49 PM, Tom Tromey wrote: Stefan == Stefan Huehner [EMAIL PROTECTED] writes: Stefan attached patch removes several unused import statement from Stefan generics-branch. Could you write a ChangeLog entry for this? And is your paperwork on file? Isn't this patch large but trivial? [*] Is copyright assignment really necessary? * http://www.gnu.org/prep/maintain/html_node/Legally- Significant.html#Legally-Significant
Re: [cp-patches] Fix interrupted read/writes
On Dec 5, 2006, at 2:52 AM, Andrew Haley wrote: Mark Wielaard writes: Hi, On Tue, 2006-12-05 at 11:04 +0100, Roman Kennke wrote: Except that you should probably also check if the thread was interrupted as the original patch does for read and write. I did it like that and it solved all my problems :-) But surely you have the same problem with any other callers of cpio_connect, or indeed cpio_*. You only fixed the bug in one place. Yeah I agree. I was wondering the same, but I decided to follow what Mark did and fix it in VMChannel. Maybe should pull all these fixes into javanio.c then? The only consumer is VMChannel. If you're going to loop around connect(2), you surely want to do so as close to the syscall as possible. The cpnio functions are (should be) trivial and inlined. What more is needed? Now, is VMChannel supposed to be POSIX-specific or not? If it is Yes, it is. supposed to be POSIX-specific, and there seem to be an awful lot of POSIXisms in there, why is it using cpio_connect() instead of simply connect(2)? I guessed that cpio_connect() was supposed to be a platform-independent abstraction on a syscall, but it isn't being used to do that: VMChannel.c isn't platform-independent. So cpio_connect() is useless, isn't it? No. This was trying to address the issues VM implementors had when it comes to user-space threads: syscalls that we use that can block indefinitely are wrapped in an easy-to-replace implementation, but otherwise the code assumes a POSIXy system. We went through this before. I thought we had enough of a consensus that POSIX was a good enough abstraction for our reference implementation of the native code, as long as we left hooks like this in place for VMs when it comes to blocking IO calls. You'll notice that we don't do this for other functions that (according to the documentation) won't block. Maybe I'm mistaken here. I'd like to hear opinions again from VM implementors on how well the cpnio stuff works for them. I think JikesRVM and Kaffe were the ones that offered user-space threading. native/jni/java-nio/javanio.h explains all of this.
Re: [cp-patches] Fix interrupted read/writes
On Dec 5, 2006, at 2:04 AM, Roman Kennke wrote: Am Dienstag, den 05.12.2006, 10:01 + schrieb Andrew Haley: Roman Kennke writes: I did it like that and it solved all my problems :-) But surely you have the same problem with any other callers of cpio_connect, or indeed cpio_*. You only fixed the bug in one place. Yeah I agree. I was wondering the same, but I decided to follow what Mark did and fix it in VMChannel. Maybe should pull all these fixes into javanio.c then? No. I explained this elsewhere, but that is not the point of the functions in javanio.c. The cpnio functions are meant to guarantee POSIX semantics, including the goofy errors you might get when using them; they only try to introduce an as-light-as-possible layer of insulation between the native code and blocking syscalls.
Re: [cp-patches] Fix interrupted read/writes
On Dec 4, 2006, at 11:19 AM, David Daney wrote: Andrew Haley wrote: Roman Kennke writes: While testing eclipse I sometimes saw interrupted reads occur. VMChannel already had a mechanism for checking the interrupted status of a thread when a system call returned early. But this wasn't used for the read() and write() methods. This patch adds the logic. And makes my eclipse happy again :) I am seeing a (possibly) related issue still: java.net.SocketException: Interrupted system call If connect(2) returns EINTR, you should retry: CPNIO_EXPORT int cpnio_connect (int fd, const struct sockaddr *addr, socklen_t addrlen) { int retcode; do { retcode = connect (fd, addr, addrlen); } while (retcode == EINTR); return retcode; } Except that you should probably also check if the thread was interrupted as the original patch does for read and write. Also, it occurs to me that VMChannel.connect should just use select for all cases -- right now, if no timeout is specified, it relies on connect(2) blocking. In other cases, the socket is put into non- blocking mode, and the timeout is applied in a call to select. Using select for all cases would clean up that function a lot. This call to select also looks like it needs EINTR protection. Thanks.
Re: [cp-patches] RFC: fix JarEntry cert lookup
On Nov 27, 2006, at 12:08 AM, Raif S. Naffah wrote: On Sunday 26 November 2006 19:58, Casey Marshall wrote: On Nov 25, 2006, at 3:59 PM, Raif S. Naffah wrote: On Tuesday 21 November 2006 08:35, Casey Marshall wrote: ... This patch fixes an issue with JarEntry objects that are created before the entry is verified... ...before your patch our implementation outputs 0, 0, and 1, and after the patch: 1, 1, and 1 which is different in both cases. Yeah, JarEntry needs to check if the entry has been verified first before looking in the certificates map. Attached is an updated patch; with it the TestOfManifest test passes. yes. please update the copyright year of JarEntry when you check in the patch. OK. any reason why you didn't address the synchronization issue in JarEntry#getCertificates()? I wasn't sure if it was needed. I think when just reading the certs mapping, it doesn't need to be (that map is created when the manifest is read, and not modified after). But, the validity mapping probably needs synchronized access. I'll look at it. Thanks.
Re: [cp-patches] RFC: fix JarEntry cert lookup
On Nov 27, 2006, at 10:52 AM, Casey Marshall wrote: On Nov 27, 2006, at 12:08 AM, Raif S. Naffah wrote: any reason why you didn't address the synchronization issue in JarEntry#getCertificates()? I wasn't sure if it was needed. It is needed, and JarFile explains that you need to lock on the JarFile object when accessing that field. I'm checking in this patch, thanks. 2006-11-27 Casey Marshall [EMAIL PROTECTED] * java/util/jar/JarEntry.java (certs): removed. (jarfile): new field. (getCertificates): read the certificates from the containing JarFile. * java/util/jar/JarFile.java (JarEnumeration.nextElement): don't fill in 'certs,' fill in 'jarfile' for the entry. (getEntry): likewise. ### Eclipse Workspace Patch 1.0 #P classpath Index: java/util/jar/JarEntry.java === RCS file: /cvsroot/classpath/classpath/java/util/jar/JarEntry.java,v retrieving revision 1.6 diff -u -r1.6 JarEntry.java --- java/util/jar/JarEntry.java 2 Jul 2005 20:32:44 - 1.6 +++ java/util/jar/JarEntry.java 28 Nov 2006 00:02:54 - @@ -1,5 +1,5 @@ /* JarEntry.java - Represents an entry in a jar file - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,6 +39,7 @@ import java.io.IOException; import java.security.cert.Certificate; +import java.util.Set; import java.util.zip.ZipEntry; /** @@ -60,7 +61,7 @@ // (Package local) fields Attributes attr; - Certificate certs[]; + JarFile jarfile; // Constructors @@ -79,7 +80,7 @@ { super(name); attr = null; -certs = null; +jarfile = null; } /** @@ -93,7 +94,7 @@ { super(entry); attr = null; -certs = null; +jarfile = null; } /** @@ -112,7 +113,7 @@ catch (IOException _) { } -certs = entry.getCertificates(); +jarfile = entry.jarfile; } // Methods @@ -153,13 +154,19 @@ */ public Certificate[] getCertificates() { -if (certs != null) +if (jarfile != null) { - return (Certificate[])certs.clone(); - } -else - { - return null; +synchronized (jarfile) + { +if (jarfile.entryCerts != null) + { +Set certs = (Set) jarfile.entryCerts.get(getName()); +if (certs != null + jarfile.verified.get(getName()) == Boolean.TRUE) + return (Certificate[]) certs.toArray(new Certificate[certs.size()]); + } + } } +return null; } } Index: java/util/jar/JarFile.java === RCS file: /cvsroot/classpath/classpath/java/util/jar/JarFile.java,v retrieving revision 1.23 diff -u -r1.23 JarFile.java --- java/util/jar/JarFile.java 20 Nov 2006 09:28:49 - 1.23 +++ java/util/jar/JarFile.java 28 Nov 2006 00:02:55 - @@ -382,19 +382,8 @@ } jarfile.signaturesRead = true; // fudge it. } - - // Include the certificates only if we have asserted that the - // signatures are valid. This means the certificates will not be - // available if the entry hasn't been read yet. - if (jarfile.entryCerts != null - jarfile.verified.get(zip.getName()) == Boolean.TRUE) - { - Set certs = (Set) jarfile.entryCerts.get(jar.getName()); - if (certs != null) - jar.certs = (Certificate[]) - certs.toArray(new Certificate[certs.size()]); - } } + jar.jarfile = jarfile; return jar; } } @@ -439,18 +428,7 @@ } signaturesRead = true; } - // See the comments in the JarEnumeration for why we do this - // check. - if (DEBUG) - debug(entryCerts= + entryCerts + verified + name - + ? + verified.get(name)); - if (entryCerts != null verified.get(name) == Boolean.TRUE) - { - Set certs = (Set) entryCerts.get(name); - if (certs != null) - jarEntry.certs = (Certificate[]) - certs.toArray(new Certificate[certs.size()]); - } +jarEntry.jarfile = this; return jarEntry; } return null;
Re: [cp-patches] RFC: fix JarEntry cert lookup
On Nov 25, 2006, at 3:59 PM, Raif S. Naffah wrote: hello Casey, On Tuesday 21 November 2006 08:35, Casey Marshall wrote: ... This patch fixes an issue with JarEntry objects that are created before the entry is verified: we used to bind the certificates to a JarEntry at creation time, so if the entry has not been verified yet, the certificates field will be null. This is contrary to the JDK behavior. This changes JarEntry to hold a pointer of its containing JarFile, and getCertificates now just accesses the entryCerts field of JarFile directly. Thus, once an entry is verified, its certificates may be looked up with a previously-initialized entry... i've added a new method to the Mauve test in gnu/testlet/java/util/jar/JarFile/TestOfManifest.java to highlight this issue. with both RI 1.4 (1.4.2_13) and 1.5 (1.5.0_09) the behavior is the same: the counts of certificates is 0, 1, and 1 respectively. before your patch our implementation outputs 0, 0, and 1, and after the patch: 1, 1, and 1 which is different in both cases. Yeah, JarEntry needs to check if the entry has been verified first before looking in the certificates map. Attached is an updated patch; with it the TestOfManifest test passes. ### Eclipse Workspace Patch 1.0 #P classpath Index: java/util/jar/JarEntry.java === RCS file: /cvsroot/classpath/classpath/java/util/jar/JarEntry.java,v retrieving revision 1.6 diff -u -r1.6 JarEntry.java --- java/util/jar/JarEntry.java 2 Jul 2005 20:32:44 - 1.6 +++ java/util/jar/JarEntry.java 26 Nov 2006 08:39:02 - @@ -39,6 +39,7 @@ import java.io.IOException; import java.security.cert.Certificate; +import java.util.Set; import java.util.zip.ZipEntry; /** @@ -60,7 +61,7 @@ // (Package local) fields Attributes attr; - Certificate certs[]; + JarFile jarfile; // Constructors @@ -79,7 +80,7 @@ { super(name); attr = null; -certs = null; +jarfile = null; } /** @@ -93,7 +94,7 @@ { super(entry); attr = null; -certs = null; +jarfile = null; } /** @@ -112,7 +113,7 @@ catch (IOException _) { } -certs = entry.getCertificates(); +jarfile = entry.jarfile; } // Methods @@ -153,13 +154,17 @@ */ public Certificate[] getCertificates() { -if (certs != null) +if (jarfile != null) { - return (Certificate[])certs.clone(); - } -else - { - return null; +// XXX synchronization??? +if (jarfile.entryCerts != null) + { +Set certs = (Set) jarfile.entryCerts.get(getName()); +if (certs != null + jarfile.verified.get(getName()) == Boolean.TRUE) + return (Certificate[]) certs.toArray(new Certificate[certs.size()]); + } } +return null; } } Index: java/util/jar/JarFile.java === RCS file: /cvsroot/classpath/classpath/java/util/jar/JarFile.java,v retrieving revision 1.23 diff -u -r1.23 JarFile.java --- java/util/jar/JarFile.java 20 Nov 2006 09:28:49 - 1.23 +++ java/util/jar/JarFile.java 26 Nov 2006 08:39:02 - @@ -382,19 +382,8 @@ } jarfile.signaturesRead = true; // fudge it. } - - // Include the certificates only if we have asserted that the - // signatures are valid. This means the certificates will not be - // available if the entry hasn't been read yet. - if (jarfile.entryCerts != null - jarfile.verified.get(zip.getName()) == Boolean.TRUE) - { - Set certs = (Set) jarfile.entryCerts.get(jar.getName()); - if (certs != null) - jar.certs = (Certificate[]) - certs.toArray(new Certificate[certs.size()]); - } } + jar.jarfile = jarfile; return jar; } } @@ -439,18 +428,7 @@ } signaturesRead = true; } - // See the comments in the JarEnumeration for why we do this - // check. - if (DEBUG) - debug(entryCerts= + entryCerts + verified + name - + ? + verified.get(name)); - if (entryCerts != null verified.get(name) == Boolean.TRUE) - { - Set certs = (Set) entryCerts.get(name); - if (certs != null) - jarEntry.certs = (Certificate[]) - certs.toArray(new Certificate[certs.size()]); - } +jarEntry.jarfile = this; return jarEntry; } return null;
Re: [cp-patches] more crypto fixes: JarFile
Marco Trudel wrote: Casey Marshall wrote: Marco Trudel wrote: Casey Marshall wrote: Marco Trudel wrote: snip Back to the patch. Comments? Hints? Your approach seems OK, but a hand-coded parser may still be faster (if only done once for the whole manifest, and if it uses a buffered stream, instead of reading a byte at a time) than using regexps for it. I don't think implementing a hand-coded parser is the right thing to do just because regexp is slow. This would need a lot of error-prone code and actually, regexp is here to do exactly parsing stuff like that. So instead of avoiding regexp because it's slow, it should be optimized (IMHO)... Sure. But you said yourself that you still thought the code was too slow, and I worry a little that your code may be fragile. I think it's too slow because of the crypto stuff. Parsing the manifest That's possible. We did a lot to optimize the symmetric crypto, but not the asymmetric stuff (that is, digital signatures). They rely on BigInteger, the Java version of which that's in Classpath has not been optimized, AFAIK. Again, Raif has a patch that uses the native GMP library, which is a lot faster. once isn't that much overhead. I still have problem that my code might be fragile, I see no more fragilness than we had before. Maybe you can explain that a little bit more in detail (see below). It's not more or less fragile, I'm just pointing out that it is (erm, might be). I do think it is a better approach than what we have now, though, so I think it should go in. I will try to take a look at the mainfest class next week. Maybe I can spare a couple of hours and do it right. So please do not yet commit it. OK. We can check this in now, though, regardless (beauty of CVS, etc.). I think I have a fix for the enumeration issue (JarEntry aren't reusable) too. No. The bytes used in the signature verification use the toByteArray method of ByteArrayOutputStream. The code may mistakenly not match the Name: line because it uses String.getBytes(). Yes, you create a byte[] by calling byteArrayOutputStream.toByteArray(). But later, you create the Name: entry this way: byte[] target = (Name: + entry.getName()).getBytes(); So you rely on the default byte representation as well. That's the only reason why I dared to do that too. Or do I miss something here? No, I wasn't saying the original code was correct. My point was that the original code doesn't introduce this conversion step for the bytes that are fed into the signature verifier, just for matching the Name: line; this would probably still produce false negatives just as often. And anyway, why repeat my mistakes? ;-) Also, I think the bikeshed should be painted Hunter Green.
Re: [cp-patches] more crypto fixes: JarFile
Marco Trudel wrote: Hello list I ran into some trouble when verifying signed jars: 1. it didn't work for classes with long names in jars 2. it was extremly slow 1. Some (or all) Manifests seem to break lines longer than 70 characters into multiple lines. The break is not always fix at 70 chars, I've seen entries where the break is later. The following line(s) then start with a space. I can see that already in the header of my original jface_3.2.0.I20060605-1400.jar (Manifest attached). The same applies for Name/Digest pairs (the name only). So they might look like this: Name: org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilter. class SHA1-Digest: DxKojrJckHaMCrOyg+hgiOPi1PI= Because such entries weren't supported, JarFile always told that these files aren't signed. My patch adds support for that. 2. Parsing the signatures of big Manifests was extremely slow. I assume that's because it worked with single bytes and reparsed the whole manifest for every file. My patch changes that procedure. Now the manifest is parsed once with some regexp and the result is reused. Some little time experience on my computer: Sun needs 0.4s to check the validity of the eclipse jface jar. JarFile needs: - unpatched: 36 seconds when used in a Sun JVM - unpatched: 8 seconds when using a GCJ compiled exe - patched: 0.7 seconds when using in a Sun JVM - patched: 1 second when using in a GCJ compiled exe It's still really slow compared to Sun. But at least not 9000% slower (did I calculate that right?)... Well, I wouldn't call that really slow -- that's a pretty huge improvement. ISTR our regex implementation being slow, and our crypto algs may not be optimized, either. Raif's native bignum patch may improve this a bit. Another thing I encountered but had no time to fix: JarFile jarFile = new JarFile(something.jar); Enumeration entries = jarFile.entries(); while(entries.hasMoreElements()) { JarEntry entry = (JarEntry)entries.nextElement(); InputStream stream = jarFile.getInputStream(entry); // read from the stream, that will parse the certificates // the following works with a sun jvm. // with classpath, one has to do the jarFile.entries() and loop // again to be able to read the certs (this will always give null) Certificate[] certs = entry.getCertificates(); } It makes sense why this wouldn't work -- the JarEntry created for the nextElement clause is probably initialized with a null certificates list, because at that point the entry hasn't been verified. JarEntry uses a private certificates field to store this, IIRC, not a callback into its jar file. I suppose it should be easy enough to change JarEntry to call into its containing JarFile for that entry's certificates, instead of using a field in JarEntry. I also run into a regular expression bug, related to .* that included newlines although the pattern was not in DOTALL mode. But, unfortunately, I can't reproduce that anymore... Back to the patch. Comments? Hints? Your approach seems OK, but a hand-coded parser may still be faster (if only done once for the whole manifest, and if it uses a buffered stream, instead of reading a byte at a time) than using regexps for it. I'd also be wary of byte[]-String-byte[] conversions, because you are wrapping each entry+hash in a String, then using String.getBytes() (what if the default character set is not what you expect?). This byte representation must match what's in the file exactly, because it is used to verify the entry. It may make sense instead to change the Manifest class to retain the byte-level representation of each entry, along with the hash value, instead of re-parsing the manifest like this -- having two parsers for the same thing is always trouble. I'm not sure why I didn't try using the existing Manifest class when I wrote the signed Jar stuff originally. If there are no objections: Can someone commit that for me? A changelog entry will follow shortly (at the latest by tomorrow morning)... thanks Marco PS: What's with the online mail archive? It stopped a couple of days (weeks?) ago. It's really usefull having an updated archive online (for google and discussion referencce). Maybe it went on vacation along with Mark ;-) Cheers.
[cp-patches] Re: preparation of VMPlainDatagramSocketImpl removal
Robert Schuster wrote: The other thing that is used from VMPlainDatagramSocketImpl is the connect() method. Is it possible for DGRAM sockets to just use VMChannel.connect instead? Yes. The original just called the common method _javanet_connect, anyway. Great. However there is just one little question left: java.net.SocketImpl.connect() throws IOException while java.net.DatagramImpl.connect() throws SocketException. I would have to change all throwings of IOException in VMChannel.connect to SocketExceptions and change affected signatures accordingly. Is this still ok? Yeah, throwing SocketException is better, in general. That's another nit about VMChannel -- those methods usually throw IOException, but the methods that wrap them only throw SocketException.
Re: [cp-patches] RFC: renamed method in KqueueSelectorImpl and removed IP_TTL field
Robert Schuster wrote: Hi, the attached patch renames a method in KqueueSelectorImpl (this conflicts with the field of the same name in GCJ) and removes the IP_TTL field in VMPlainDatagramSocketImpl. The latter is seemingly not used anywhere and causes a problem during GCJ compilation. Please comment whether this change is ok? Sure, the kqueue bits are fine (but, I'm at a loss at why they would be needed ;-) VMPlainDatagramSocketImpl is, I think, mostly deprecated at this point (favoring instead VMPlainSocketImpl, so more of the code is shared). I don't know if it's safe yet to remove it completely, though. I haven't looked. Thanks.
Re: [cp-patches] javax.crypto fixes
Marco Trudel wrote: I fixed some stuff in javax.crypto: Thanks for looking at this. Some of these parts of javax.crypto were badly implemented, and I have to claim responsibility for that. 1. decryption with padding was broken/wrong handled 2. CipherOutputStream was completly broken/unusuable 3. PKCS7 did an unnecessary test 1. decryption with padding needs to keep back the last block for final unpadding when doFinal() is called. This wasn't done. doFinal() lead to an exception. Actually, padded decrypting only worked correct when all data was passed by doFinal(byte[]) or when there where update() calls that filled the data to a multiple of the blocklengh and doFinal was called with the rest of the data. This fixes CiperInputStream as well, because it relies on the correct doFinal() handling of the cipher class. Understood. Sounds fine. 2. CipherOutputstream had a lot of code that did nothing except leading to a NullPointerException when calling write(...) (outBuffer was never initialized). It looks to me like the code should have worked around the bugs in CipherAdapter. But that should have been done in CipherInputStream?! I don't know. I wrote all of these, so all I can do is claim ignorance on how this stuff was supposed to work :-\ 3. PKCS7 unpadding tested a value that was just read with itself. Fixed it because I was already reading it... Nothing big... OK. Any comments? Hints? It certainly looks more correct, to my eyes. I haven't tried this out yet, but it looks much better, and certainly simpler. I have no committing rights and the copyright assignment papers are not yet arrived with mail. This might be a problem... Yeah, we won't be able to accept this patch until you have a copyright assignment on file. But if it is your intention to contribute this, then it's just a matter of time. Have we gotten you the correct forms? Maybe Mark can tell if this process is moving forward or not. @@ -447,16 +459,20 @@ break; case IMode.DECRYPTION: int padLen; +byte[] buf3 = new byte[buf.length + partLen]; try { -padLen = pad.unpad(buf, 0, buf.length); +if(partLen != 16) throw new WrongPaddingException(); What is this constant? Does this work for all block sizes and all padding schemes? [...] +{ + out.write(cipher.doFinal()); + out.flush(); + out.close(); + } catch (javax.crypto.IllegalBlockSizeException ibse) + { + throw new IOException(ibse.toString()); + } catch (javax.crypto.BadPaddingException bpe) + { + throw new IOException(bpe.toString()); + } It would be better to chain the exceptions here, and to omit the explicit 'javax.crypto' package references (I know, they were in the original).
[cp-patches] FYI: fix for PR 29190
This fixes some issues with the epoll selector, related to handling canceled keys properly, and handling keys registered to closed channels. I'm also taking the approach where the events byte buffer -- a direct byte buffer whose pointer we pass directly to epoll_wait -- is allocated once when the selector is created, and is reallocated as needed when new keys are registered. We keep doubling the capacity as needed, until the buffer grows to a certain size, then we start incrementally increasing the capacity; if the capacity is more than twice what is needed, the buffer is reallocated to half its current size. This should allocating (potentially large) buffers on each call to select(), and shouldn't waste too much memory. 2006-09-29 Casey Marshall [EMAIL PROTECTED] PR 29190 * gnu/java/nio/EpollSelectionKeyImpl.java: extend `AbstractSelectionKey.' (cancel, isValid): removed. * gnu/java/nio/EpollSelectorImpl.java (cancelledKeys): removed. (events): new field. (INITIAL_CAPACITY, MAX_DOUBLING_CAPACITY, CAPACITY_INCREMENT): new fields. (clinit): initialize those constants. (init): don't initialize `cancelledKeys;' initialize `events.' (doSelect): deregister cancelled keys; remove keys attached to closed channels; wrap `epoll_wait' in `begin' and `end' calls; use `events' buffer; reallocate `events' buffer if needed. (register): reallocate `events' buffer if needed. (reallocateBuffer): new method. (cancel): removed. Index: gnu/java/nio/EpollSelectionKeyImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectionKeyImpl.java,v retrieving revision 1.1 diff -u -r1.1 EpollSelectionKeyImpl.java --- gnu/java/nio/EpollSelectionKeyImpl.java 20 Sep 2006 21:39:41 - 1.1 +++ gnu/java/nio/EpollSelectionKeyImpl.java 30 Sep 2006 05:13:49 - @@ -43,11 +43,12 @@ import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; +import java.nio.channels.spi.AbstractSelectionKey; /** * @author Casey Marshall ([EMAIL PROTECTED]) */ -public class EpollSelectionKeyImpl extends SelectionKey +public class EpollSelectionKeyImpl extends AbstractSelectionKey { final int fd; private final EpollSelectorImpl selector; @@ -67,15 +68,6 @@ } /* (non-Javadoc) - * @see java.nio.channels.SelectionKey#cancel() - */ - public void cancel() - { -cancelled = true; -selector.cancel(this); - } - - /* (non-Javadoc) * @see java.nio.channels.SelectionKey#channel() */ public SelectableChannel channel() @@ -113,14 +105,6 @@ } /* (non-Javadoc) - * @see java.nio.channels.SelectionKey#isValid() - */ - public boolean isValid() - { -return valid; - } - - /* (non-Javadoc) * @see java.nio.channels.SelectionKey#readyOps() */ public int readyOps() Index: gnu/java/nio/EpollSelectorImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectorImpl.java,v retrieving revision 1.4 diff -u -r1.4 EpollSelectorImpl.java --- gnu/java/nio/EpollSelectorImpl.java 27 Sep 2006 21:30:44 - 1.4 +++ gnu/java/nio/EpollSelectorImpl.java 30 Sep 2006 05:13:49 - @@ -42,6 +42,7 @@ import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.AbstractSelectableChannel; @@ -75,8 +76,12 @@ private final HashMap keys; private Set selectedKeys; - private final Set cancelledKeys; private Thread waitingThread; + private ByteBuffer events; + + private static final int INITIAL_CAPACITY; + private static final int MAX_DOUBLING_CAPACITY; + private static final int CAPACITY_INCREMENT; static { @@ -87,6 +92,10 @@ sizeof_struct_epoll_event = sizeof_struct(); else sizeof_struct_epoll_event = -1; + +INITIAL_CAPACITY = 64 * sizeof_struct_epoll_event; +MAX_DOUBLING_CAPACITY = 1024 * sizeof_struct_epoll_event; +CAPACITY_INCREMENT = 128 * sizeof_struct_epoll_event; } public EpollSelectorImpl(SelectorProvider provider) @@ -96,7 +105,7 @@ epoll_fd = epoll_create(DEFAULT_EPOLL_SIZE); keys = new HashMap(); selectedKeys = null; -cancelledKeys = new HashSet(); +events = ByteBuffer.allocateDirect(INITIAL_CAPACITY); } /* (non-Javadoc) @@ -131,6 +140,7 @@ { synchronized (keys) { + Set cancelledKeys = cancelledKeys(); synchronized (cancelledKeys) { for (Iterator it = cancelledKeys.iterator(); it.hasNext(); ) @@ -140,25 +150,45 @@ key.valid = false; keys.remove(Integer.valueOf(key.fd)); it.remove(); +deregister(key
[cp-patches] FYI: loopify scatter/gather file I/O
readScattering and writeGathering seem really unhappy on Darwin for files, and calling the latter seems to return 0 too often (ie, all the time). I don't know if this is a bug in those methods or not, but I don't think it makes sense to use readv/writev for file I/O, when a loop will suffice. And, this makes Azureus extremely unhappy. 2006-09-24 Casey Marshall [EMAIL PROTECTED] * gnu/java/nio/FileChannelImpl.java (read): call `read' in a loop, don't use `readScattering.' (write): call `write' in a loop, don't use `writeGathering.' Committed. ### Eclipse Workspace Patch 1.0 #P classpath Index: gnu/java/nio/FileChannelImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/FileChannelImpl.java,v retrieving revision 1.17 diff -u -r1.17 FileChannelImpl.java --- gnu/java/nio/FileChannelImpl.java 17 Sep 2006 07:31:41 - 1.17 +++ gnu/java/nio/FileChannelImpl.java 25 Sep 2006 06:44:06 - @@ -253,7 +253,18 @@ public long read (ByteBuffer[] dsts, int offset, int length) throws IOException { -return ch.readScattering(dsts, offset, length); +int n = offset + length; +long read = 0; +if (offset 0 || length 0 || n dsts.length) + throw new ArrayIndexOutOfBoundsException(); +for (int i = offset; i n; i++) + { +int ret = read(dsts[i]); +if (ret == -1) + break; +read += ret; + } +return read; } public int write (ByteBuffer src) throws IOException @@ -292,7 +303,13 @@ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { -return ch.writeGathering(srcs, offset, length); +int n = offset + length; +long written = 0; +if (offset 0 || length 0 || n srcs.length) + throw new ArrayIndexOutOfBoundsException(); +for (int i = offset; i n; i++) + written += write(srcs[i]); +return written; } public MappedByteBuffer map (FileChannel.MapMode mode,
[cp-patches] FYI: fix writeGathering
If a gathering write (i.e., a write that takes an array of buffers) is given a list of buffers, and the initial buffers have no remaining elements, then the `write' method *should* skip these buffers, and use the first buffer that has remaining elements. Since on some operating systems, gathering writes can only take up to sixteen input sources, it is important that we advance to some buffer that has something in it. Otherwise, we'll see nothing in the first sixteen buffers, and won't write anything. This reverts my previous change to FileChannelImpl, since `writev' seems to work OK on files. This should fix the issue I saw with Azureus, and also clears two Mauve regressions I introduced (I think the tests are wrong, but this fixes them regardless). Scattering reads are probably also similarly broken; I'll look at that next. 2006-09-25 Casey Marshall [EMAIL PROTECTED] * gnu/java/nio/FileChannelImpl.java (read): revert back to using `readScattering.' (write): revert back to using `writeGathering.' * vm/reference/gnu/java/nio/VMChannel.java (writeGathering): find the first buffer that has data remaining, and start at that one. Committed. ### Eclipse Workspace Patch 1.0 #P classpath Index: gnu/java/nio/FileChannelImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/FileChannelImpl.java,v retrieving revision 1.18 diff -u -r1.18 FileChannelImpl.java --- gnu/java/nio/FileChannelImpl.java 25 Sep 2006 06:49:18 - 1.18 +++ gnu/java/nio/FileChannelImpl.java 25 Sep 2006 21:44:16 - @@ -253,18 +253,7 @@ public long read (ByteBuffer[] dsts, int offset, int length) throws IOException { -int n = offset + length; -long read = 0; -if (offset 0 || length 0 || n dsts.length) - throw new ArrayIndexOutOfBoundsException(); -for (int i = offset; i n; i++) - { -int ret = read(dsts[i]); -if (ret == -1) - break; -read += ret; - } -return read; +return ch.readScattering(dsts, offset, length); } public int write (ByteBuffer src) throws IOException @@ -303,13 +292,7 @@ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { -int n = offset + length; -long written = 0; -if (offset 0 || length 0 || n srcs.length) - throw new ArrayIndexOutOfBoundsException(); -for (int i = offset; i n; i++) - written += write(srcs[i]); -return written; +return ch.writeGathering(srcs, offset, length); } public MappedByteBuffer map (FileChannel.MapMode mode, Index: vm/reference/gnu/java/nio/VMChannel.java === RCS file: /cvsroot/classpath/classpath/vm/reference/gnu/java/nio/VMChannel.java,v retrieving revision 1.2 diff -u -r1.2 VMChannel.java --- vm/reference/gnu/java/nio/VMChannel.java17 Sep 2006 07:31:43 - 1.2 +++ vm/reference/gnu/java/nio/VMChannel.java25 Sep 2006 21:44:16 - @@ -196,7 +196,7 @@ { if (offset + length dsts.length) throw new IndexOutOfBoundsException(offset + length dsts.length); - + return readScattering(nfd.getNativeFD(), dsts, offset, length); } @@ -275,6 +275,21 @@ if (offset + length srcs.length) throw new IndexOutOfBoundsException(offset + length srcs.length); +// A gathering write is limited to 16 buffers; when writing, ensure +// that we have at least one buffer with something in it in the 16 +// buffer window starting at offset. +while (!srcs[offset].hasRemaining() offset srcs.length) + offset++; + +// There are no buffers with anything to write. +if (offset == srcs.length) + return 0; + +// If we advanced `offset' so far that we don't have `length' +// buffers left, reset length to only the remaining buffers. +if (length srcs.length - offset) + length = srcs.length - offset; + return writeGathering(nfd.getNativeFD(), srcs, offset, length); } @@ -673,10 +688,10 @@ public String toString() { - if (!valid) -return invalid; if (closed) return closed; + if (!valid) +return invalid; return String.valueOf(native_fd); }
[cp-patches] FYI: more fixes for epoll selector
Here is another little fix for the epoll selector, which deals with the epoll man pages not being exactly clear on what error values it returns. I've been able to run Azureus, unmodified, on Ubuntu GNU/Linux with jamvm! Even running on jamvm, it's really snappy. The kqueue selector doesn't quite work as well, yet, but I'm looking at this now. 2006-09-22 Casey Marshall [EMAIL PROTECTED] * gnu/java/nio/EpollSelectorImpl.java (doSelect): remove keys after we delete them. (selectedKeys): return an empty set if nothing's been selected. * native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c (Java_gnu_java_nio_EpollSelectorImpl_epoll_1delete): don't throw an exception on EBADF. (Java_gnu_java_nio_EpollSelectorImpl_epoll_1wait): don't throw exception on EINTR, just return 0. Have fun. ### Eclipse Workspace Patch 1.0 #P classpath Index: gnu/java/nio/EpollSelectorImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectorImpl.java,v retrieving revision 1.2 diff -u -r1.2 EpollSelectorImpl.java --- gnu/java/nio/EpollSelectorImpl.java 21 Sep 2006 23:23:02 - 1.2 +++ gnu/java/nio/EpollSelectorImpl.java 23 Sep 2006 06:39:20 - @@ -139,6 +139,7 @@ epoll_delete(epoll_fd, key.fd); key.valid = false; keys.remove(new Integer(key.fd)); +it.remove(); } // Don't bother if we have nothing to select. @@ -177,6 +178,8 @@ */ public Set selectedKeys() { +if (selectedKeys == null) + return Collections.EMPTY_SET; return selectedKeys; } Index: native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c === RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c,v retrieving revision 1.2 diff -u -r1.2 gnu_java_nio_EpollSelectorImpl.c --- native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c20 Sep 2006 22:28:08 - 1.2 +++ native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c23 Sep 2006 06:39:20 - @@ -150,8 +150,8 @@ event.data.fd = fd; #ifdef TRACE_EPOLL - fprintf (stderr, %s: adding struct epoll_event { events: %o; data.fd: %d }\n, - __FUNCTION__, event.events, event.data.fd); + fprintf (stderr, %s: adding struct epoll_event { events: %o; data.fd: %d } to %d\n, + __FUNCTION__, event.events, event.data.fd, efd); #endif /* TRACE_EPOLL */ if (epoll_ctl (efd, EPOLL_CTL_ADD, fd, event) == -1) @@ -197,8 +197,8 @@ event.data.fd = fd; #ifdef TRACE_EPOLL - fprintf (stderr, %s: modding struct epoll_event { events: %o; data.fd: %d }\n, - __FUNCTION__, event.events, event.data.fd); + fprintf (stderr, %s: modding struct epoll_event { events: %o; data.fd: %d } on %d\n, + __FUNCTION__, event.events, event.data.fd, efd); #endif /* TRACE_EPOLL */ if (epoll_ctl (efd, EPOLL_CTL_MOD, fd, event) == -1) @@ -235,7 +235,7 @@ event.data.fd = fd; #ifdef TRACE_EPOLL - fprintf (stderr, %s: delete events on fd %d\n, __FUNCTION__, fd); + fprintf (stderr, %s: delete events on fd %d for %d\n, __FUNCTION__, fd, efd); #endif /* TRACE_EPOLL */ /* Older kernel versions require a non-null `event' parameter, @@ -246,7 +246,11 @@ if (ENOSYS == errno) JCL_ThrowException (env, java/lang/InternalError, strerror (errno)); - else if (ENOENT == errno) + /* XXX the docs here seem a little strange. If `fd' is closed, + epoll_ctl returns EBADF; but the docs say that this happens + only when efd is invalid. Go figure. + */ + else if (ENOENT == errno || EBADF == errno) return; /* fd is closed; it's already removed. */ else JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); @@ -282,16 +286,19 @@ } #ifdef TRACE_EPOLL - fprintf (stderr, %s: events: %p; num_events: %d; timeout: %d\n, - __FUNCTION__, p, num_events, timeout); + fprintf (stderr, %s: events: %p; num_events: %d; timeout: %d; efd: %d\n, + __FUNCTION__, p, num_events, timeout, efd); #endif /* TRACE_EPOLL */ ret = epoll_wait (efd, events, num_events, timeout); + if (ret == -1) { if (ENOSYS == errno) JCL_ThrowException (env, java/lang/InternalError, strerror (errno)); + else if (EINTR == errno) +ret = 0; else JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); } Index: ChangeLog === RCS file: /cvsroot/classpath/classpath/ChangeLog,v retrieving revision 1.8600 diff -u -r1.8600 ChangeLog --- ChangeLog 23 Sep 2006 05:17:45 - 1.8600 +++ ChangeLog 23 Sep 2006 06:39:20 - @@ -1,5 +1,16 @@ 2006-09-22 Casey Marshall [EMAIL PROTECTED
[cp-patches] patch for PR 29190
Attached is a patch that *might* fix PR 29190. I don't have a Linux system to test this on anymore :-(, so this may not work. The issue was really that the epoll selector (and the kqueue selector, now that I think about it) doesn't use the SPI interface correctly, meaning that de-registering and canceling keys doesn't work quite right. ### Eclipse Workspace Patch 1.0 #P classpath Index: gnu/java/nio/EpollSelectorImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectorImpl.java,v retrieving revision 1.3 diff -u -r1.3 EpollSelectorImpl.java --- gnu/java/nio/EpollSelectorImpl.java 23 Sep 2006 06:44:13 - 1.3 +++ gnu/java/nio/EpollSelectorImpl.java 24 Sep 2006 03:51:10 - @@ -75,7 +75,6 @@ private final HashMap keys; private Set selectedKeys; - private final Set cancelledKeys; private Thread waitingThread; static @@ -96,7 +95,6 @@ epoll_fd = epoll_create(DEFAULT_EPOLL_SIZE); keys = new HashMap(); selectedKeys = null; -cancelledKeys = new HashSet(); } /* (non-Javadoc) @@ -131,6 +129,7 @@ { synchronized (keys) { + Set cancelledKeys = cancelledKeys(); synchronized (cancelledKeys) { for (Iterator it = cancelledKeys.iterator(); it.hasNext(); ) @@ -140,6 +139,7 @@ key.valid = false; keys.remove(new Integer(key.fd)); it.remove(); +deregister(key); } // Don't bother if we have nothing to select. @@ -149,10 +149,19 @@ ByteBuffer selected = ByteBuffer.allocateDirect(keys.size() * sizeof_struct_epoll_event); -waitingThread = Thread.currentThread(); -int ret = epoll_wait(epoll_fd, selected, keys.size(), timeout); -Thread.interrupted(); -waitingThread = null; +int ret; +try + { +begin(); +waitingThread = Thread.currentThread(); +ret = epoll_wait(epoll_fd, selected, keys.size(), timeout); + } +finally + { +Thread.interrupted(); +waitingThread = null; +end(); + } HashSet s = new HashSet(ret); for (int i = 0; i ret; i++) @@ -255,14 +264,6 @@ epoll_modify(epoll_fd, key.fd, ops); } - void cancel(EpollSelectionKeyImpl key) - { -synchronized (cancelledKeys) -{ - cancelledKeys.add(key); -} - } - /** * Tell if epoll is supported by this system, and support was compiled in. * Index: gnu/java/nio/EpollSelectionKeyImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectionKeyImpl.java,v retrieving revision 1.1 diff -u -r1.1 EpollSelectionKeyImpl.java --- gnu/java/nio/EpollSelectionKeyImpl.java 20 Sep 2006 21:39:41 - 1.1 +++ gnu/java/nio/EpollSelectionKeyImpl.java 24 Sep 2006 03:51:10 - @@ -43,11 +43,12 @@ import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; +import java.nio.channels.spi.AbstractSelectionKey; /** * @author Casey Marshall ([EMAIL PROTECTED]) */ -public class EpollSelectionKeyImpl extends SelectionKey +public class EpollSelectionKeyImpl extends AbstractSelectionKey { final int fd; private final EpollSelectorImpl selector; @@ -67,15 +68,6 @@ } /* (non-Javadoc) - * @see java.nio.channels.SelectionKey#cancel() - */ - public void cancel() - { -cancelled = true; -selector.cancel(this); - } - - /* (non-Javadoc) * @see java.nio.channels.SelectionKey#channel() */ public SelectableChannel channel() @@ -113,14 +105,6 @@ } /* (non-Javadoc) - * @see java.nio.channels.SelectionKey#isValid() - */ - public boolean isValid() - { -return valid; - } - - /* (non-Javadoc) * @see java.nio.channels.SelectionKey#readyOps() */ public int readyOps()
[cp-patches] FYI: fix VMFile.list on Darwin
Our usage of `readdir' wasn't portable: on Darwin, you get a NULL return value, but `errno' will be zero. We were expecting errno to be nonzero in that case. This had the side effect that we'd keep reallocating the filename array, because we'd be looping on the same value for `filename', and this would exhaust memory. I also took the liberty of adding a check for readdir_r, and use it in cpio_readDir if it is available. 2006-09-22 Casey Marshall [EMAIL PROTECTED] * configure.ac (AC_CHECK_FUNCS): check for `readdir_r.' * native/jni/java-io/java_io_VMFile.c (Java_java_io_VMFile_list): allocate `filename,' and handle changes to `cpio_readDir.' * native/jni/native-lib/cpio.c (cpio_readDir): use `readdir_r' if available; copy the filename into the destination buffer; return an error code if readdir returns NULL, but errno is 0. * native/jni/native-lib/cpio.h (cpio_readDir): change second parameter to `const char *.' Committed. ### Eclipse Workspace Patch 1.0 #P classpath Index: native/jni/java-io/java_io_VMFile.c === RCS file: /cvsroot/classpath/classpath/native/jni/java-io/java_io_VMFile.c,v retrieving revision 1.12 diff -u -r1.12 java_io_VMFile.c --- native/jni/java-io/java_io_VMFile.c 21 Aug 2006 23:34:45 - 1.12 +++ native/jni/java-io/java_io_VMFile.c 23 Sep 2006 01:38:51 - @@ -593,7 +593,7 @@ int result; char **filelist; void *handle; - const char *filename; + const char *filename = (const char *) JCL_malloc (env, FILENAME_MAX); unsigned long int filelist_count, max_filelist_count; char **tmp_filelist; jclass str_clazz; @@ -630,7 +630,7 @@ max_filelist_count = REALLOC_SIZE; /* read the files from the directory */ - result = cpio_readDir (handle, filename); + result = cpio_readDir (handle, filename); while (result == CPNATIVE_OK) { if ((strcmp (filename, .) != 0) (strcmp (filename, ..) != 0)) @@ -666,9 +666,11 @@ } /* read next directory entry */ - result = cpio_readDir (handle, filename); + result = cpio_readDir (handle, filename); } + JCL_free (env, filename); + /* close directory */ result = cpio_closeDir (handle); @@ -693,6 +695,9 @@ JCL_free (env, filelist); return 0; } + + (*env)-DeleteLocalRef (env, str_clazz); + for (i = 0; i filelist_count; i++) { /* create new string */ Index: native/jni/native-lib/cpio.h === RCS file: /cvsroot/classpath/classpath/native/jni/native-lib/cpio.h,v retrieving revision 1.2 diff -u -r1.2 cpio.h --- native/jni/native-lib/cpio.h21 Aug 2006 23:34:46 - 1.2 +++ native/jni/native-lib/cpio.h23 Sep 2006 01:38:51 - @@ -79,6 +79,6 @@ JNIEXPORT int cpio_openDir (const char *dirname, void **handle); JNIEXPORT int cpio_closeDir (void *handle); -JNIEXPORT int cpio_readDir (void *handle, const char **filename); +JNIEXPORT int cpio_readDir (void *handle, const char *filename); #endif Index: native/jni/native-lib/cpio.c === RCS file: /cvsroot/classpath/classpath/native/jni/native-lib/cpio.c,v retrieving revision 1.3 diff -u -r1.3 cpio.c --- native/jni/native-lib/cpio.c31 Aug 2006 19:56:03 - 1.3 +++ native/jni/native-lib/cpio.c23 Sep 2006 01:38:51 - @@ -448,14 +448,28 @@ } -int cpio_readDir (void *handle, const char **filename) +int cpio_readDir (void *handle, const char *filename) { +#ifdef HAVE_READDIR_R + struct dirent dent; +#endif /* HAVE_READDIR_R */ struct dirent *dBuf; +#ifdef HAVE_READDIR_R + readdir_r ((DIR *) handle, dent, dBuf); +#else dBuf = readdir((DIR *)handle); +#endif /* HAVE_READDIR_R */ + if (dBuf == NULL) -return errno; +{ + /* Some OS's (OS X) return NULL on end-of-dir, but + don't set errno to anything. */ + if (errno == 0) +return ENOENT; /* Whatever. */ + return errno; +} - *filename = dBuf-d_name; + strncpy (filename, dBuf-d_name, FILENAME_MAX); return 0; } Index: configure.ac === RCS file: /cvsroot/classpath/classpath/configure.ac,v retrieving revision 1.184 diff -u -r1.184 configure.ac --- configure.ac20 Sep 2006 21:39:41 - 1.184 +++ configure.ac23 Sep 2006 01:38:51 - @@ -375,7 +375,8 @@ mmap munmap mincore msync madvise getpagesize sysconf \ lstat readlink \ inet_aton inet_addr inet_pton \ - getifaddrs kqueue kevent epoll_create]) + getifaddrs kqueue kevent epoll_create \ + readdir_r ]) LIBMAGIC= AC_CHECK_LIB(magic, magic_open, LIBMAGIC=-lmagic)
Re: [cp-patches] FYI: fix VMFile.list on Darwin
Casey Marshall wrote: Our usage of `readdir' wasn't portable: on Darwin, you get a NULL return value, but `errno' will be zero. We were expecting errno to be nonzero in that case. This had the side effect that we'd keep reallocating the filename array, because we'd be looping on the same value for `filename', and this would exhaust memory. I also took the liberty of adding a check for readdir_r, and use it in cpio_readDir if it is available. 2006-09-22 Casey Marshall [EMAIL PROTECTED] * configure.ac (AC_CHECK_FUNCS): check for `readdir_r.' * native/jni/java-io/java_io_VMFile.c (Java_java_io_VMFile_list): allocate `filename,' and handle changes to `cpio_readDir.' * native/jni/native-lib/cpio.c (cpio_readDir): use `readdir_r' if available; copy the filename into the destination buffer; return an error code if readdir returns NULL, but errno is 0. * native/jni/native-lib/cpio.h (cpio_readDir): change second parameter to `const char *.' Yup, this code introduced warnings. Fixed with this: 2006-09-22 Casey Marshall [EMAIL PROTECTED] * native/jni/java-io/java_io_VMFile.c (Java_java_io_VMFile_list): remove `const' from `filename.' * native/jni/native-lib/cpio.c (cpio_readDir): remove `const' from `filename.' * native/jni/native-lib/cpio.h (cpio_readDir): likewise.
[cp-patches] FYI: Epoll and DatagramSocket bugs
Paul Jenner helpfully pointed out some problems when running Azureus with the epoll selector, and the modified DatagramSocket implementation. 2006-09-21 Casey Marshall [EMAIL PROTECTED] * gnu/java/net/PlainDatagramSocketImpl.java (send): ignore `InterruptedIOException;' try again if it gets thrown. (receive): likewise, but re-throw `SocketTimeoutException.' * gnu/java/nio/EpollSelectorImpl.java (doSelect): just return 0 if we have nothing to select. Committed. ### Eclipse Workspace Patch 1.0 #P classpath Index: gnu/java/nio/EpollSelectorImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectorImpl.java,v retrieving revision 1.1 diff -u -r1.1 EpollSelectorImpl.java --- gnu/java/nio/EpollSelectorImpl.java 20 Sep 2006 21:39:41 - 1.1 +++ gnu/java/nio/EpollSelectorImpl.java 21 Sep 2006 23:16:22 - @@ -140,6 +140,10 @@ key.valid = false; keys.remove(new Integer(key.fd)); } + +// Don't bother if we have nothing to select. +if (keys.isEmpty()) + return 0; ByteBuffer selected = ByteBuffer.allocateDirect(keys.size() * sizeof_struct_epoll_event); Index: gnu/java/net/PlainDatagramSocketImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/net/PlainDatagramSocketImpl.java,v retrieving revision 1.11 diff -u -r1.11 PlainDatagramSocketImpl.java --- gnu/java/net/PlainDatagramSocketImpl.java 17 Sep 2006 07:31:41 - 1.11 +++ gnu/java/net/PlainDatagramSocketImpl.java 21 Sep 2006 23:16:22 - @@ -41,6 +41,7 @@ import gnu.java.nio.VMChannel; import java.io.IOException; +import java.io.InterruptedIOException; import java.lang.reflect.Field; import java.net.DatagramPacket; import java.net.DatagramSocketImpl; @@ -49,6 +50,7 @@ import java.net.NetworkInterface; import java.net.SocketAddress; import java.net.SocketException; +import java.net.SocketTimeoutException; import java.nio.ByteBuffer; /** @@ -259,7 +261,17 @@ throw new NullPointerException(); if (port = 0) throw new SocketException(invalid port + port); -channel.send(buf, new InetSocketAddress(remote, port)); +while (true) + { +try + { +channel.send(buf, new InetSocketAddress(remote, port)); + } +catch (InterruptedIOException ioe) + { +// Ignore; interrupted system call. + } + } } } @@ -278,7 +290,23 @@ ByteBuffer buf = ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength()); -SocketAddress addr = channel.receive(buf); +SocketAddress addr = null; +while (true) + { +try + { +addr = channel.receive(buf); +break; + } +catch (SocketTimeoutException ste) + { +throw ste; + } +catch (InterruptedIOException iioe) + { +// Ignore. Loop. + } + } if (addr != null) packet.setSocketAddress(addr); packet.setLength(buf.position() - packet.getOffset());
Re: [cp-patches] FYI: Epoll and DatagramSocket bugs
David Daney wrote: Casey Marshall wrote: -channel.send(buf, new InetSocketAddress(remote, port)); +while (true) + { +try + { +channel.send(buf, new InetSocketAddress(remote, port)); + } +catch (InterruptedIOException ioe) + { +// Ignore; interrupted system call. + } + } } How does the while loop exit? Just wondering, At the `break' statement I forgot to insert :-)
Re: [cp-patches] FYI: Fix distcheck for native/jni/java-nio
Mark Wielaard wrote: + gnu_java_nio_channels_FileChannelImpl.c \ This is obsolete, and FileChannelImpl now contains no native methods. I know I shoulda removed the file, but I wield `cvs rm' with care.
[cp-patches] FYI: fix SocketChannelImpl.isConnected
Jeroen helped flush a brain fart out of my head; this patch fixes the definition of `isConnected' in SocketChannel -- if we have a connection pending, meaning that we initiated a nonblocking connect, which did not succeed immediately, and finishConnect was not called after the connection completes, then we should return false for `isConnected.' 2006-09-20 Casey Marshall [EMAIL PROTECTED] * gnu/java/nio/SocketChannelImpl.java (finishConnect): don't call `isConnected.' (isConnected): return false if `connectionPending' is true. Committed. ### Eclipse Workspace Patch 1.0 #P classpath Index: ChangeLog === RCS file: /cvsroot/classpath/classpath/ChangeLog,v retrieving revision 1.8577 diff -u -r1.8577 ChangeLog --- ChangeLog 20 Sep 2006 18:26:24 - 1.8577 +++ ChangeLog 20 Sep 2006 21:04:45 - @@ -1,3 +1,9 @@ +2006-09-20 Casey Marshall [EMAIL PROTECTED] + + * gnu/java/nio/SocketChannelImpl.java (finishConnect): don't + call `isConnected.' + (isConnected): return false if `connectionPending' is true. + 2006-09-20 Francis Kung [EMAIL PROTECTED] PR 29011 Index: gnu/java/nio/SocketChannelImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/SocketChannelImpl.java,v retrieving revision 1.30 diff -u -r1.30 SocketChannelImpl.java --- gnu/java/nio/SocketChannelImpl.java 17 Sep 2006 07:31:41 - 1.30 +++ gnu/java/nio/SocketChannelImpl.java 20 Sep 2006 21:04:45 - @@ -175,14 +175,15 @@ connectionPending = !connected; return connected; } - - public boolean finishConnect () + + public boolean finishConnect() throws IOException { if (!isOpen()) throw new ClosedChannelException(); - -if (isConnected()) + +InetSocketAddress remote = channel.getPeerAddress(); +if (remote != null) { connectionPending = false; return true; @@ -196,6 +197,10 @@ public boolean isConnected() { +// Wait until finishConnect is called before transitioning to +// connected. +if (connectionPending) + return false; try { InetSocketAddress remote = channel.getPeerAddress();
[cp-patches] FYI: epoll selector
I'm checking this in. I won't be able to test if the fallback code works on 2.4 kernels, however. 2006-09-20 Casey Marshall [EMAIL PROTECTED] * configure.ac (AC_CHECK_HEADERS): check for `sys/epoll.h.' (AC_CHECK_FUNCS): check for `epoll_create.' * gnu/java/nio/EpollSelectionKeyImpl.java: new file. * gnu/java/nio/EpollSelectorImpl.java: new file. * gnu/java/nio/SelectorProviderImpl.java (epoll_failed): new class field. (openSelector): return epoll selector if requested and available. * include/Makefile.am (H_FILES): add gnu_java_nio_EpollSelectorImpl.h. (gnu_java_nio_EpollSelectorImpl.h): new target. * include/gnu_java_nio_EpollSelectorImpl.h: new file. * native/jni/java-nio/Makefile.am (libjavanio_la_SOURCES): add gnu_java_nio_EpollSelectorImpl.c. * native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c: new file. ### Eclipse Workspace Patch 1.0 #P classpath Index: include/Makefile.am === RCS file: /cvsroot/classpath/classpath/include/Makefile.am,v retrieving revision 1.70 diff -u -r1.70 Makefile.am --- include/Makefile.am 17 Sep 2006 07:31:41 - 1.70 +++ include/Makefile.am 20 Sep 2006 21:32:43 - @@ -128,6 +128,7 @@ $(top_srcdir)/include/gnu_java_net_VMPlainDatagramSocketImpl.h \ $(top_srcdir)/include/gnu_java_net_VMPlainSocketImpl.h \ $(top_srcdir)/include/gnu_java_net_local_LocalSocketImpl.h \ +$(top_srcdir)/include/gnu_java_nio_EpollSelectorImpl.h \ $(top_srcdir)/include/gnu_java_nio_FileChannelImpl.h \ $(top_srcdir)/include/gnu_java_nio_KqueueSelectorImpl.h \ $(top_srcdir)/include/gnu_java_nio_VMChannel.h \ @@ -227,6 +228,9 @@ $(top_srcdir)/include/gnu_java_nio_KqueueSelectorImpl.h: $(top_srcdir)/gnu/java/nio/KqueueSelectorImpl.java $(JAVAH) -o $@ gnu.java.nio.KqueueSelectorImpl +$(top_srcdir)/include/gnu_java_nio_EpollSelectorImpl.h: $(top_srcdir)/gnu/java/nio/EpollSelectorImpl.java + $(JAVAH) -o $@ gnu.java.nio.EpollSelectorImpl + $(top_srcdir)/include/gnu_java_nio_charset_iconv_IconvDecoder.h: $(top_srcdir)/gnu/java/nio/charset/iconv/IconvDecoder.java $(JAVAH) -o $@ gnu.java.nio.charset.iconv.IconvDecoder $(top_srcdir)/include/gnu_java_nio_charset_iconv_IconvEncoder.h: $(top_srcdir)/gnu/java/nio/charset/iconv/IconvEncoder.java Index: gnu/java/nio/SelectorProviderImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/SelectorProviderImpl.java,v retrieving revision 1.9 diff -u -r1.9 SelectorProviderImpl.java --- gnu/java/nio/SelectorProviderImpl.java 17 Sep 2006 07:31:41 - 1.9 +++ gnu/java/nio/SelectorProviderImpl.java 20 Sep 2006 21:32:43 - @@ -53,6 +53,7 @@ private static final String SELECTOR_IMPL_KQUEUE = kqueue; private static final String SELECTOR_IMPL_EPOLL = epoll; private static final String SELECTOR_IMPL = gnu.java.nio.selectorImpl; + private static boolean epoll_failed = false; public SelectorProviderImpl () { @@ -76,12 +77,31 @@ String selectorImpl = default; if (KqueueSelectorImpl.kqueue_supported()) selectorImpl = SELECTOR_IMPL_KQUEUE; +if (EpollSelectorImpl.epoll_supported() !epoll_failed) + selectorImpl = SELECTOR_IMPL_EPOLL; selectorImpl = SystemProperties.getProperty(SELECTOR_IMPL, selectorImpl); if (selectorImpl.equals(SELECTOR_IMPL_KQUEUE)) return new KqueueSelectorImpl(this); + if (selectorImpl.equals(SELECTOR_IMPL_EPOLL)) - throw new UnsupportedOperationException(epoll selector not yet implemented); + { +// We jump through these hoops because even though epoll may look +// like it's available (sys/epoll.h exists, and you can link against +// all the epoll functions) it may not be available in the kernel +// (especially 2.4 kernels), meaning you will get ENOSYS at run time. +// +// Madness! +try + { +return new EpollSelectorImpl(this); + } +catch (InternalError e) + { +// epoll_create throws this on ENOSYS. +epoll_failed = true; + } + } return new SelectorImpl (this); } Index: configure.ac === RCS file: /cvsroot/classpath/classpath/configure.ac,v retrieving revision 1.183 diff -u -r1.183 configure.ac --- configure.ac17 Sep 2006 07:31:41 - 1.183 +++ configure.ac20 Sep 2006 21:32:43 - @@ -357,7 +357,7 @@ fcntl.h \ sys/mman.h \ magic.h \ -sys/event.h]) +sys/event.h sys/epoll.h]) AC_EGREP_HEADER(uint32_t, stdint.h, AC_DEFINE(HAVE_INT32_DEFINED, 1, [Define to 1 if you have uint32_t])) AC_EGREP_HEADER(uint32_t, inttypes.h
[cp-patches] FYI: epoll: deleting closed file descriptors
A file descriptor is removed from an epoll descriptor when it is closed; trying to remove it later harmlessly returns ENOENT. This handles that case. 2006-09-20 Casey Marshall [EMAIL PROTECTED] * native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c (Java_gnu_java_nio_EpollSelectorImpl_epoll_1delete): ignore ENOENT. Committed. ### Eclipse Workspace Patch 1.0 #P classpath Index: native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c === RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c,v retrieving revision 1.1 diff -u -r1.1 gnu_java_nio_EpollSelectorImpl.c --- native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c20 Sep 2006 21:39:41 - 1.1 +++ native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c20 Sep 2006 22:21:33 - @@ -246,6 +246,8 @@ if (ENOSYS == errno) JCL_ThrowException (env, java/lang/InternalError, strerror (errno)); + else if (ENOENT == errno) +return; /* fd is closed; it's already removed. */ else JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); }
[cp-patches] FYI: mention epoll selectors in NEWS
2006-09-20 Casey Marshall [EMAIL PROTECTED] * NEWS: mention epoll selector along with the kqueue one. ### Eclipse Workspace Patch 1.0 #P classpath Index: NEWS === RCS file: /cvsroot/classpath/classpath/NEWS,v retrieving revision 1.168 diff -u -r1.168 NEWS --- NEWS17 Sep 2006 07:31:41 - 1.168 +++ NEWS20 Sep 2006 22:33:58 - @@ -19,9 +19,9 @@ * Added aton method to vm/reference/java/net/VMInetAddress.java. * NetworkInterface has been implemented for systems that provide the `getifaddrs' function. -* A java.nio.channels.Selector implementation based on the - kqueue/kevent notification mechanism has been added for Mac OS X and - BSD systems. +* java.nio.channels.Selector implementations have been added that use + the kqueue notification mechanism on Mac OS X and *BSD, and that use + the epoll notification mechanism on Linux 2.6. * java.nio has been refactored to support more non-blocking operations natively. Blocking IO classes have been refactored to call non-blocking classes. Non-blocking accepts, connects, and
Re: [cp-patches] RFC: epoll-based selector
David Daney wrote: Casey Marshall wrote: Here is a patch to implement a Selector using the epoll_wait call on Linux, the preferred event notification facility in the 2.6 series kernels. This seems to test OK, so I'll probably just commit this soon. It compiles OK on systems that do and don't have epoll, and on Linux the Mauve tests for Selector pass. I have not tested the patch, but am afraid that it may fail on linux systems without epoll support (2.4.x kernels I think lack epoll). I am running glibc-2.3.3 which has sys/epoll.h but I think that the epoll syscalls may fail at runtime with ENOSYS. Also I am running gcj/libgcj cross compiler and do not know how this patch will interact with libgcj. Well those are my concerns. I guess if things get broken by this we can add a configure switch to manually disable it. Thanks for mentioning this. I suppose I should have known that trying to write software for Linux would be a minefield of crap like this :-\ Does libgcj use Classpath's NIO? I thought for a lot of these things libgcj had its own implementation in CNI. Note, too, that you can disable epoll (or kqueue) at run time by setting the system property gnu.java.nio.selectorImpl to any string other than epoll (or kqueue), and use the old select() based version. Maybe we can detect ENOSYS at run time, and disable epoll selectors. Thanks.
Re: [cp-patches] RFC: epoll-based selector
Casey Marshall wrote: Note, too, that you can disable epoll (or kqueue) at run time by setting the system property gnu.java.nio.selectorImpl to any string other than epoll (or kqueue), and use the old select() based version. Maybe we can detect ENOSYS at run time, and disable epoll selectors. OK. I've attached a revised patch that tries epoll selectors if support was compiled in, and if that fails with ENOSYS, we set a flag that disables trying it again. In any case, if creating an epoll selector fails, we fall back on the select- (actually, whatever backs VMSelector) based version. Warning, I've neither tried, nor tried to compile, this yet. ### Eclipse Workspace Patch 1.0 #P classpath Index: include/Makefile.am === RCS file: /cvsroot/classpath/classpath/include/Makefile.am,v retrieving revision 1.70 diff -u -r1.70 Makefile.am --- include/Makefile.am 17 Sep 2006 07:31:41 - 1.70 +++ include/Makefile.am 19 Sep 2006 21:46:56 - @@ -128,6 +128,7 @@ $(top_srcdir)/include/gnu_java_net_VMPlainDatagramSocketImpl.h \ $(top_srcdir)/include/gnu_java_net_VMPlainSocketImpl.h \ $(top_srcdir)/include/gnu_java_net_local_LocalSocketImpl.h \ +$(top_srcdir)/include/gnu_java_nio_EpollSelectorImpl.h \ $(top_srcdir)/include/gnu_java_nio_FileChannelImpl.h \ $(top_srcdir)/include/gnu_java_nio_KqueueSelectorImpl.h \ $(top_srcdir)/include/gnu_java_nio_VMChannel.h \ @@ -227,6 +228,9 @@ $(top_srcdir)/include/gnu_java_nio_KqueueSelectorImpl.h: $(top_srcdir)/gnu/java/nio/KqueueSelectorImpl.java $(JAVAH) -o $@ gnu.java.nio.KqueueSelectorImpl +$(top_srcdir)/include/gnu_java_nio_EpollSelectorImpl.h: $(top_srcdir)/gnu/java/nio/EpollSelectorImpl.java + $(JAVAH) -o $@ gnu.java.nio.EpollSelectorImpl + $(top_srcdir)/include/gnu_java_nio_charset_iconv_IconvDecoder.h: $(top_srcdir)/gnu/java/nio/charset/iconv/IconvDecoder.java $(JAVAH) -o $@ gnu.java.nio.charset.iconv.IconvDecoder $(top_srcdir)/include/gnu_java_nio_charset_iconv_IconvEncoder.h: $(top_srcdir)/gnu/java/nio/charset/iconv/IconvEncoder.java Index: gnu/java/nio/SelectorProviderImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/nio/SelectorProviderImpl.java,v retrieving revision 1.9 diff -u -r1.9 SelectorProviderImpl.java --- gnu/java/nio/SelectorProviderImpl.java 17 Sep 2006 07:31:41 - 1.9 +++ gnu/java/nio/SelectorProviderImpl.java 19 Sep 2006 21:46:56 - @@ -53,6 +53,7 @@ private static final String SELECTOR_IMPL_KQUEUE = kqueue; private static final String SELECTOR_IMPL_EPOLL = epoll; private static final String SELECTOR_IMPL = gnu.java.nio.selectorImpl; + private static boolean epoll_failed = false; public SelectorProviderImpl () { @@ -76,12 +77,31 @@ String selectorImpl = default; if (KqueueSelectorImpl.kqueue_supported()) selectorImpl = SELECTOR_IMPL_KQUEUE; +if (EpollSelectorImpl.epoll_supported() !epoll_failed) + selectorImpl = SELECTOR_IMPL_EPOLL; selectorImpl = SystemProperties.getProperty(SELECTOR_IMPL, selectorImpl); if (selectorImpl.equals(SELECTOR_IMPL_KQUEUE)) return new KqueueSelectorImpl(this); + if (selectorImpl.equals(SELECTOR_IMPL_EPOLL)) - throw new UnsupportedOperationException(epoll selector not yet implemented); + { +// We jump through these hoops because even though epoll may look +// like it's available (sys/epoll.h exists, and you can link against +// all the epoll functions) it may not be available in the kernel +// (especially 2.4 kernels), meaning you will get ENOSYS at run time. +// +// Madness! +try + { +return new EpollSelectorImpl(this); + } +catch (InternalError e) + { +// epoll_create throws this on ENOSYS. +epoll_failed = true; + } + } return new SelectorImpl (this); } Index: configure.ac === RCS file: /cvsroot/classpath/classpath/configure.ac,v retrieving revision 1.183 diff -u -r1.183 configure.ac --- configure.ac17 Sep 2006 07:31:41 - 1.183 +++ configure.ac19 Sep 2006 21:46:56 - @@ -357,7 +357,7 @@ fcntl.h \ sys/mman.h \ magic.h \ -sys/event.h]) +sys/event.h sys/epoll.h]) AC_EGREP_HEADER(uint32_t, stdint.h, AC_DEFINE(HAVE_INT32_DEFINED, 1, [Define to 1 if you have uint32_t])) AC_EGREP_HEADER(uint32_t, inttypes.h, AC_DEFINE(HAVE_INT32_DEFINED, 1, [Define to 1 if you have uint32_t])) @@ -375,7 +375,7 @@ mmap munmap mincore msync madvise getpagesize sysconf \ lstat readlink \ inet_aton inet_addr inet_pton \ - getifaddrs kqueue kevent
Re: [cp-patches] RFC: epoll-based selector
Anthony Green wrote: On Mon, 2006-09-18 at 18:38 -0700, Casey Marshall wrote: Here is a patch to implement a Selector using the epoll_wait call on Linux, the preferred event notification facility in the 2.6 series kernels. This is great Casey. Have you ever tried running Azureus? It stresses both the nio selector code as well as our crypto infrastructure -- two areas where you are expert. I realize that GNU Classpath != libgcj, but it's worth mentioning that azureus still doesn't run nearly as smoothly on gcj as it does on Sun java. I blame nio and crypto, but I don't have any proof :-) I'm curious to hear how azureus fares on vanilla GNU Classpath (vs Sun, for instance). I haven't run Azureus on classpath or GCJ yet. I'd actually be surprised if the epoll selector even makes a difference in that app (even if Classpath's default selector does some just plain inefficient things), unless you really are interacting with thousands of peers at once.
Re: [cp-patches] Patch: RFC: enable 1.4 methods in jessie
Tom Tromey wrote: I'd like some comment before committing this. An FC bug report led to this note: http://www.mail-archive.com/jessie-discuss@nongnu.org/msg00059.html This patch is simply the same thing, applied to Classpath. Any reason this should not go in? No reason. It looks fine. Thanks for tracking this.
[cp-patches] Re: RFC: small nio change
Jeroen Frijters wrote: Hi Casey, I would like to remove the dependence on VMChannel from Socket and ServerSocket (as this breaks the layering). Do you agree with this patch? I think this should be OK. Refresh my memory, though: in ServerSocket and Socket `impl' is created in a constructor, right? And it is only set to null in close, right? Because otherwise testing `impl == null' won't make a correct definition of isClosed(). Thanks.
[cp-patches] FYI: remove debug printf
Removes an errant debug printf. 2006-09-18 Casey Marshall [EMAIL PROTECTED] * native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c (Java_gnu_java_net_VMPlainSocketImpl_listen): remove debug printf. ### Eclipse Workspace Patch 1.0 #P classpath Index: native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c === RCS file: /cvsroot/classpath/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c,v retrieving revision 1.7 diff -u -r1.7 gnu_java_net_VMPlainSocketImpl.c --- native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c17 Sep 2006 07:31:43 - 1.7 +++ native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c19 Sep 2006 01:24:21 - @@ -155,7 +155,6 @@ /* listen is not a blocking system call */ if ((ret = listen (fd, backlog)) == -1) JCL_ThrowException (env, IO_EXCEPTION, strerror (errno)); - printf(listen returns %d\n, ret); }
[cp-patches] RFC: epoll-based selector
from your version. */ + + +package gnu.java.nio; + +import gnu.classpath.Configuration; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.spi.AbstractSelectableChannel; +import java.nio.channels.spi.AbstractSelector; +import java.nio.channels.spi.SelectorProvider; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * An implementation of [EMAIL PROTECTED] Selector} that uses the epoll event + * notification mechanism on GNU/Linux. + * + * @author Casey Marshall ([EMAIL PROTECTED]) + */ +public class EpollSelectorImpl extends AbstractSelector +{ + // XXX is this reasonable? Does it matter? + private static final int DEFAULT_EPOLL_SIZE = 128; + private static final int sizeof_struct_epoll_event; + + private static final int OP_ACCEPT = SelectionKey.OP_ACCEPT; + private static final int OP_CONNECT = SelectionKey.OP_CONNECT; + private static final int OP_READ= SelectionKey.OP_READ; + private static final int OP_WRITE = SelectionKey.OP_WRITE; + + /** our epoll file descriptor. */ + private int epoll_fd; + + private final HashMap keys; + private Set selectedKeys; + private final Set cancelledKeys; + private Thread waitingThread; + + static + { +if (Configuration.INIT_LOAD_LIBRARY) + System.loadLibrary(javanio); + +if (epoll_supported()) + sizeof_struct_epoll_event = sizeof_struct(); +else + sizeof_struct_epoll_event = -1; + } + + public EpollSelectorImpl(SelectorProvider provider) +throws IOException + { +super(provider); +epoll_fd = epoll_create(DEFAULT_EPOLL_SIZE); +keys = new HashMap(); +selectedKeys = null; +cancelledKeys = new HashSet(); + } + + /* (non-Javadoc) + * @see java.nio.channels.Selector#keys() + */ + public Set keys() + { +return new HashSet(keys.values()); + } + + /* (non-Javadoc) + * @see java.nio.channels.Selector#select() + */ + public int select() throws IOException + { +return doSelect(-1); + } + + /* (non-Javadoc) + * @see java.nio.channels.Selector#select(long) + */ + public int select(long timeout) throws IOException + { +if (timeout Integer.MAX_VALUE) + throw new IllegalArgumentException(timeout is too large); +if (timeout 0) + throw new IllegalArgumentException(invalid timeout); +return doSelect((int) timeout); + } + + private int doSelect(int timeout) throws IOException + { +synchronized (keys) +{ + synchronized (cancelledKeys) + { +for (Iterator it = cancelledKeys.iterator(); it.hasNext(); ) + { +EpollSelectionKeyImpl key = (EpollSelectionKeyImpl) it.next(); +epoll_delete(epoll_fd, key.fd); +key.valid = false; +keys.remove(new Integer(key.fd)); + } + +ByteBuffer selected = + ByteBuffer.allocateDirect(keys.size() * sizeof_struct_epoll_event); + +waitingThread = Thread.currentThread(); +int ret = epoll_wait(epoll_fd, selected, keys.size(), timeout); +Thread.interrupted(); +waitingThread = null; + +HashSet s = new HashSet(ret); +for (int i = 0; i ret; i++) + { +selected.position(i * sizeof_struct_epoll_event); +ByteBuffer b = selected.slice(); +int fd = selected_fd(b); +EpollSelectionKeyImpl key + = (EpollSelectionKeyImpl) keys.get(new Integer(fd)); +if (key == null) + throw new IOException(fd was selected, but no key found); +key.selectedOps = selected_ops(b) key.interestOps; +s.add(key); + } +selectedKeys = s; +return ret; + } +} + } + + /* (non-Javadoc) + * @see java.nio.channels.Selector#selectedKeys() + */ + public Set selectedKeys() + { +return selectedKeys; + } + + /* (non-Javadoc) + * @see java.nio.channels.Selector#selectNow() + */ + public int selectNow() throws IOException + { +return doSelect(0); + } + + /* (non-Javadoc) + * @see java.nio.channels.Selector#wakeup() + */ + public Selector wakeup() + { +try + { +waitingThread.interrupt(); + } +catch (NullPointerException npe) + { + } +return this; + } + + /* (non-Javadoc) + * @see java.nio.channels.spi.AbstractSelector#implCloseSelector() + */ + protected void implCloseSelector() throws IOException + { +VMChannel.close(epoll_fd); + } + + /* (non-Javadoc) + * @see java.nio.channels.spi.AbstractSelector#register(java.nio.channels.spi.AbstractSelectableChannel, int, java.lang.Object) + */ + protected SelectionKey register(AbstractSelectableChannel ch, int ops, Object att) + { +if (!(ch instanceof VMChannelOwner)) + throw new IllegalArgumentException
[cp-patches] FYI: big IO, net, NIO change
OK. Hibbego. I'm checking in my patch that I've been writing about recently. Again, the patch itself is large, so I'll just post a link to it: http://metastatic.org/source/io-nio-final.patch To summarize, this patch: * Implements most non-blocking operations for real -- that is, using native function calls on file descriptors in non-blocking mode. Blocking-IO APIs now defer to the NIO API, in blocking mode. * Refactors our code and the VM interfaces to keep no native state (such as file descriptor integers) in core classes, but instead in VM classes. A number of VM classes have, unfortunately, been modified to support this, but I think in general these changes are for the best. * Implements NetworkInterface using getifaddrs. * Adds a Selector that uses kqueue, the preferred event notification mechanism on OS X. There is more work to do here. In particular, too much code in the core classes knows about file descriptor integers; this too should be moved to the VM classes. Also, an epoll-based selector for Linux would be nice to have. If this breaks anything at all (the Mauve tests I've run, on OS X and Linux, seem to show that this code works well) please complain (fiercely if you must ;-) to me about it. It's a little uncouth to check in such a large patch, sure, but I think this is the good and correct way to implement IO in Java. I've updated NEWS to explain these changes. The change log is also large, but detailed about lots of little changes: 2006-09-16 Casey Marshall [EMAIL PROTECTED] * NEWS: updated. * configure.ac (AC_CHECK_HEADERS): check for `sys/event.h'. (AC_CHECK_FUNCS): add checks for readv, writev, getifaddrs, kqueue, and kevent. (HAVE_INET6): define if IPv6 is supported. * gnu/java/net/PlainDatagramSocketImpl.java (channel): new field. (native_fd): removed. (impl): new field. (init): throw IOException; initialize fields. (finalize): removed. (getNativeFD): removed. (bind): use `PlainSocketImpl.bind.' (create): use `PlainSocketImpl.initSocket.' (disconnect): use `PlainSocketImpl.disconnect.' (getLocalPort): new method. (send): use `VMChannel.send.' (receive): use `VMChannel.receive.' (setOption): use `PlainSocketImpl.setOption.' (getOption): use `PlainSocketImpl.getOption.' (close): use `VMChannel.State.close.' (join): use `PlainSocketImpl.join.' (leave): use `PlainSocketImpl.leave.' (joinGroup, leaveGroup): implemented. * gnu/java/net/PlainSocketImpl.java: make non-final. (native_fd): removed. (impl): new field. (channel): new field. (init): initialize `impl.' (finalize, getNativeFD): removed. (setOption): use `PlainSocketImpl.setOption.' (getOption): use `PlainSocketImpl.getOption.' (shutdownInput): use `PlainSocketImpl.shutdownInput.' (shutdownOutput): use `PlainSocketImpl.shutdownOutput.' (create): create `channel,' initialize `impl's native state. (connect): use `connect(SocketAddress, int).' (connect): use `SocketChannelImpl.connect;' initialize `address' and `port.' (bind): use `VMPlainSocketImpl.bind.' (listen): use `VMPlainSocketImpl.listen.' (accept): use `SocketChannelImpl.accept.' (available): use `VMChannel.available.' (close): use `PlainSocketImpl.close.' (sendUrgentData): use `PlainSocketImpl.sendUrgentData.' (getVMChannel, getInetAddress, getLocalPort, getLocalAddress, getPort): new methods. (SocketInputStream.read): use `VMChannel.read.' (SocketInputStream.read): use `SocketChannel.read.' (SocketOutputStream.write): use `VMChannel.write.' (SocketOutputStream.write): use `SocketChannel.write.' * gnu/java/nio/DatagramChannelImpl.java: implement VMChannel. (channel): new field. (init): initialize `channel.' (implCloseSelectableChannel): use `VMChannel.close.' (implConfigureBlocking): use `VMChannel.setBlocking.' (connect): use `VMChannel.connect.' (disconnect): use `VMChannel.disconnect.' (isConnected): use `VMChannel.getPeerAddress.' (write): use `VMChannel.write.' (write): use `VMChannel.writeGathering.' (read): use `VMChannel.read.' (read): use `VMChannel.readScattering.' (receive): use `VMChannel.receive.' (send): use `VMChannel.send.' (getVMChannel): new method. * gnu/java/nio/DatagramChannelSelectionKey.java (getNativeFD): access native FD through VMChannel.State. * gnu/java/nio/FileChannelImpl.java: moved from gnu/java/nio/channels/FileChannelImpl.java. * gnu/java/nio/FileLockImpl.java: fix imports. * gnu/java/nio/KqueueSelectionKeyImpl.java: new file. * gnu/java/nio/KqueueSelectorImpl.java
[cp-patches] FYI: big IO, net, NIO change
OK. Hibbego. I'm checking in my patch that I've been writing about recently. Again, the patch itself is large, so I'll just post a link to it: http://metastatic.org/source/io-nio-final.patch To summarize, this patch: * Implements most non-blocking operations for real -- that is, using native function calls on file descriptors in non-blocking mode. Blocking-IO APIs now defer to the NIO API, in blocking mode. * Refactors our code and the VM interfaces to keep no native state (such as file descriptor integers) in core classes, but instead in VM classes. A number of VM classes have, unfortunately, been modified to support this, but I think in general these changes are for the best. * Implements NetworkInterface using getifaddrs. * Adds a Selector that uses kqueue, the preferred event notification mechanism on OS X. There is more work to do here. In particular, too much code in the core classes knows about file descriptor integers; this too should be moved to the VM classes. Also, an epoll-based selector for Linux would be nice to have. If this breaks anything at all (the Mauve tests I've run, on OS X and Linux, seem to show that this code works well) please complain (fiercely if you must ;-) to me about it. It's a little uncouth to check in such a large patch, sure, but I think this is the good and correct way to implement IO in Java. I've updated NEWS to explain these changes. The change log is also large, but detailed about lots of little changes: 2006-09-16 Casey Marshall [EMAIL PROTECTED] * NEWS: updated. * configure.ac (AC_CHECK_HEADERS): check for `sys/event.h'. (AC_CHECK_FUNCS): add checks for readv, writev, getifaddrs, kqueue, and kevent. (HAVE_INET6): define if IPv6 is supported. * gnu/java/net/PlainDatagramSocketImpl.java (channel): new field. (native_fd): removed. (impl): new field. (init): throw IOException; initialize fields. (finalize): removed. (getNativeFD): removed. (bind): use `PlainSocketImpl.bind.' (create): use `PlainSocketImpl.initSocket.' (disconnect): use `PlainSocketImpl.disconnect.' (getLocalPort): new method. (send): use `VMChannel.send.' (receive): use `VMChannel.receive.' (setOption): use `PlainSocketImpl.setOption.' (getOption): use `PlainSocketImpl.getOption.' (close): use `VMChannel.State.close.' (join): use `PlainSocketImpl.join.' (leave): use `PlainSocketImpl.leave.' (joinGroup, leaveGroup): implemented. * gnu/java/net/PlainSocketImpl.java: make non-final. (native_fd): removed. (impl): new field. (channel): new field. (init): initialize `impl.' (finalize, getNativeFD): removed. (setOption): use `PlainSocketImpl.setOption.' (getOption): use `PlainSocketImpl.getOption.' (shutdownInput): use `PlainSocketImpl.shutdownInput.' (shutdownOutput): use `PlainSocketImpl.shutdownOutput.' (create): create `channel,' initialize `impl's native state. (connect): use `connect(SocketAddress, int).' (connect): use `SocketChannelImpl.connect;' initialize `address' and `port.' (bind): use `VMPlainSocketImpl.bind.' (listen): use `VMPlainSocketImpl.listen.' (accept): use `SocketChannelImpl.accept.' (available): use `VMChannel.available.' (close): use `PlainSocketImpl.close.' (sendUrgentData): use `PlainSocketImpl.sendUrgentData.' (getVMChannel, getInetAddress, getLocalPort, getLocalAddress, getPort): new methods. (SocketInputStream.read): use `VMChannel.read.' (SocketInputStream.read): use `SocketChannel.read.' (SocketOutputStream.write): use `VMChannel.write.' (SocketOutputStream.write): use `SocketChannel.write.' * gnu/java/nio/DatagramChannelImpl.java: implement VMChannel. (channel): new field. (init): initialize `channel.' (implCloseSelectableChannel): use `VMChannel.close.' (implConfigureBlocking): use `VMChannel.setBlocking.' (connect): use `VMChannel.connect.' (disconnect): use `VMChannel.disconnect.' (isConnected): use `VMChannel.getPeerAddress.' (write): use `VMChannel.write.' (write): use `VMChannel.writeGathering.' (read): use `VMChannel.read.' (read): use `VMChannel.readScattering.' (receive): use `VMChannel.receive.' (send): use `VMChannel.send.' (getVMChannel): new method. * gnu/java/nio/DatagramChannelSelectionKey.java (getNativeFD): access native FD through VMChannel.State. * gnu/java/nio/FileChannelImpl.java: moved from gnu/java/nio/channels/FileChannelImpl.java. * gnu/java/nio/FileLockImpl.java: fix imports. * gnu/java/nio/KqueueSelectionKeyImpl.java: new file. * gnu/java/nio/KqueueSelectorImpl.java
Re: [cp-patches] FYI: big IO, net, NIO change
Casey Marshall wrote: OK. Hibbego. I'm checking in my patch that I've been writing about recently. There was a warning about an unused parameter in jcl.c. It didn't get mentioned on Darwin, but does on Linux. The attached fixes it. 2006-09-17 Casey Marshall [EMAIL PROTECTED] * native/jni/classpath/jcl.c (JNI_OnLoad): mark `reserved' as unused. Committed. Index: native/jni/classpath/jcl.c === RCS file: /cvsroot/classpath/classpath/native/jni/classpath/jcl.c,v retrieving revision 1.24 diff -u -r1.24 jcl.c --- native/jni/classpath/jcl.c 17 Sep 2006 07:31:43 - 1.24 +++ native/jni/classpath/jcl.c 17 Sep 2006 19:09:22 - @@ -51,15 +51,15 @@ /* * Cached Pointer class info. */ -static jclass rawDataClass; -static jfieldID rawData_fid; -static jmethodID rawData_mid; +static jclass rawDataClass = NULL; +static jfieldID rawData_fid = NULL; +static jmethodID rawData_mid = NULL; /* * JNI OnLoad constructor. */ jint -JNI_OnLoad (JavaVM *vm, void *reserved) +JNI_OnLoad (JavaVM *vm, void *reserved __attribute__((unused))) { JNIEnv *env; void *envp;
Re: [cp-patches] updated: IO, net, and NIO
Thomas Fitzsimmons wrote: Casey Marshall wrote: Casey Marshall wrote: http://metastatic.org/source/io-nio.patch http://metastatic.org/source/io-nio2.patch I've updated these again. One of these days I'll take the time to apply these to a clean checkout, and test that. Promise. Or, hey, is this OK to commit yet? I get fewer Mauve failures now, and this may be easier to debug once I've committed it. Yes, this fixes a major problem with java.net.ServerSocket.accept so I think it should go in right away. OK. I'll try to check it in this weekend, unless someone objects before then. I'll check in my patches to the JCL code, and to implement NetworkInterface, too. They both seem to work fine on jamvm and cacao.
Re: [cp-patches] updated: IO, net, and NIO
Thomas Fitzsimmons wrote: OK, the new patches build for me (though I had to add KqueueSelectorImpl lines to include/Makefile.am) but now running rmiregistry under cacao fails like this: $ gdb --args /notnfs/fitzsim/install/classpath-inst/bin/cacao gnu.java.rmi.registry.RegistryImpl GNU gdb Red Hat Linux (6.3.0.0-1.122rh) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type show copying to see the conditions. There is absolutely no warranty for GDB. Type show warranty for details. This GDB was configured as i386-redhat-linux-gnu...Using host libthread_db library /lib/libthread_db.so.1. (gdb) r Starting program: /notnfs/fitzsim/install/classpath-inst/bin/cacao gnu.java.rmi.registry.RegistryImpl Reading symbols from shared object read from target memory...done. Loaded system supplied DSO at 0x2d3000 [Thread debugging using libthread_db enabled] [New Thread -1209055568 (LWP 8805)] [New Thread 2132896 (LWP 8808)] [New Thread 1186720 (LWP 8809)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1209055568 (LWP 8805)] 0x00387c3d in GetDirectBufferAddress (env=0x8343038, buf=0x83a0a10) at /home/fitzsim/workspace/cacao/src/native/jni.c:5324 5324return (void *) address-data; (gdb) p address $1 = (gnu_classpath_Pointer32 *) 0x0 (gdb) bt #0 0x00387c3d in GetDirectBufferAddress (env=0x8343038, buf=0x83a0a10) at /home/fitzsim/workspace/cacao/src/native/jni.c:5324 #1 0x0023ee02 in JCL_init_buffer (env=0x8343038, buf=0xbfd00f80, bbuf=0x83a0a10) at /home/fitzsim/workspace/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c:139 #2 0x0023ff56 in Java_gnu_java_nio_VMChannel_read__ILjava_nio_ByteBuffer_2 (env=0x8343038, o=0x839f098, fd=8, bbuf=0x83a0a10) at /home/fitzsim/workspace/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c:368 #3 0x00852c02 in ?? () #4 0x08343038 in ?? () #5 0x0839f098 in ?? () #6 0x0008 in ?? () #7 0x083a0a10 in ?? () #8 0x0023ff20 in Java_gnu_java_nio_VMChannel_write__ILjava_nio_ByteBuffer_2 () at /home/fitzsim/workspace/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c:445 Previous frame inner to this frame (corrupt stack?) (gdb) Have you seen this failure? No, I haven't. Does cacao support GetDirectBufferAddress properly? There may be a bug there.
Re: [cp-patches] updated: IO, net, and NIO
Mark Wielaard wrote: On Wed, 2006-09-13 at 18:01 -0400, Thomas Fitzsimmons wrote: I'm testing these patches to see if they fix the RMI problem I'm having (which may be unrelated): [...] Were you aware of this problem? I think it was introduced by Mark's native layer merge. They were definitely introduced by my merging in the new native-layer branch stuff from Guilhem. Sorry about that. I was secretly hoping Casey's rewrite would automagically fix them. I have not yet tried the patch, but the corresponding Mauve tests (that worked before the merge, but failed after) are: FAIL: org.omg.CORBA.ORB.parallelRunTest FAIL: org.omg.CORBA.ORB.DirectTest FAIL: org.omg.CORBA_2_3.ORB.ValueTypeTest FAIL: org.omg.PortableServer.POAOperations.poa_POA_test FAIL: org.omg.PortableInterceptor.Interceptor.testInterceptors They are all related to socket timeouts. Some of those org.omg tests work for me. I do get two failures, however. I'm suspicious of this broken pipe error: FAIL: org.omg.CORBA.ORB.RequestTest line 134: string [2] -- uncaught exception: org.omg.CORBA.MARSHAL at gnu.CORBA.GIOP.MessageHeader.write(MessageHeader.java:374) at gnu.CORBA.gnuRequest.submit(gnuRequest.java:831) at gnu.CORBA.gnuRequest.p_invoke(gnuRequest.java:940) at gnu.CORBA.gnuRequest.invoke(gnuRequest.java:510) at gnu.testlet.org.omg.CORBA.ORB.RequestTest.testParameters(RequestTest.java:134) at gnu.testlet.org.omg.CORBA.ORB.RequestTest.test(RequestTest.java:90) at RunnerProcess.runtest(RunnerProcess.java:337) at RunnerProcess.runAndReport(RunnerProcess.java:392) at RunnerProcess.main(RunnerProcess.java:219) org.omg.CORBA.MARSHAL: IOException while writing message header Minor: 0 (0). Completed: not completed at gnu.CORBA.Version.write(Version.java:215) at gnu.CORBA.GIOP.MessageHeader.write(MessageHeader.java:367) at gnu.CORBA.gnuRequest.submit(gnuRequest.java:831) at gnu.CORBA.IorDelegate.invoke(IorDelegate.java:184) FAIL: org.omg.PortableServer.POAOperations.poa_POA_test at org.omg.CORBA.portable.ObjectImpl._invoke(ObjectImpl.java:202) line 481: Exc:org.omg.CORBA.MARSHAL: IOException while writing message header Minor: 0 (0). Completed: not completed:java.io.IOException: Broken pipe [1] -- forced fail at gnu.testlet.org.omg.PortableServer.POAOperations.communication.poa_comTesterStub.passCharacters(poa_comTesterStub.java:138) at gnu.testlet.org.omg.PortableServer.POAOperations.poa_POA_test.test_RETAIN_Activation(poa_POA_test.java:109) at gnu.testlet.org.omg.PortableServer.POAOperations.poa_POA_test.test(poa_POA_test.java:467) at RunnerProcess.runtest(RunnerProcess.java:337) at RunnerProcess.runAndReport(RunnerProcess.java:392) at RunnerProcess.main(RunnerProcess.java:219) Caused by: java.io.IOException: Broken pipe at gnu.java.nio.VMChannel.write(Native Method) at gnu.java.nio.VMChannel.write(VMChannel.java:323) at gnu.java.net.PlainSocketImpl$SocketOutputStream.write(PlainSocketImpl.java:567) at java.io.DataOutputStream.write(DataOutputStream.java:115) at gnu.CORBA.Version.write(Version.java:210) ...10 more
Re: [cp-patches] updated: IO, net, and NIO
Casey Marshall wrote: http://metastatic.org/source/io-nio.patch http://metastatic.org/source/io-nio2.patch I've updated these again. One of these days I'll take the time to apply these to a clean checkout, and test that. Promise. Or, hey, is this OK to commit yet? I get fewer Mauve failures now, and this may be easier to debug once I've committed it.
[cp-patches] updated: IO, net, and NIO
I've updated my patch that updates IO, net, and NIO to better support non-blocking IO, which also includes my kqueue Selector, and the implementation of NetworkInterface. Along with implementing real non-blocking IO, I've rewritten parts of the IO and net code to use the NIO implementation, reducing the amount of code use. I've also tried to make the JNI code as simple as possible, and to abstract out as much of this native code logic into the VM interface classes (IOW, the native logic is private instance data of our VM interface reference implementation). I only get a few Mauve failures with this patch; most of them look like my tree is just out of date (serialization, URL and InetAddress, none of which I've changed here). Mauve may not be testing everything, though, so it's likely that there are bugs lurking here. The patches are big, so I'll just link to them here: http://metastatic.org/source/io-nio.patch http://metastatic.org/source/io-nio2.patch I haven't cleaned everything up, yet, so there are still some obsolete files that aren't removed yet, and I haven't addressed SIGPIPE at all. I've only tested this so far on Darwin/x86, but I'll try this on Linux/x86 too. Comments appreciated! Especially on whether or not this is good enough to commit, or what's lacking. Thanks.
Re: [cp-patches] updated: IO, net, and NIO
Thomas Fitzsimmons wrote: Hi, Casey Marshall wrote: I've updated my patch that updates IO, net, and NIO to better support non-blocking IO, which also includes my kqueue Selector, and the implementation of NetworkInterface. Along with implementing real non-blocking IO, I've rewritten parts of the IO and net code to use the NIO implementation, reducing the amount of code use. I've also tried to make the JNI code as simple as possible, and to abstract out as much of this native code logic into the VM interface classes (IOW, the native logic is private instance data of our VM interface reference implementation). I only get a few Mauve failures with this patch; most of them look like my tree is just out of date (serialization, URL and InetAddress, none of which I've changed here). Mauve may not be testing everything, though, so it's likely that there are bugs lurking here. The patches are big, so I'll just link to them here: http://metastatic.org/source/io-nio.patch http://metastatic.org/source/io-nio2.patch I haven't cleaned everything up, yet, so there are still some obsolete files that aren't removed yet, and I haven't addressed SIGPIPE at all. I've only tested this so far on Darwin/x86, but I'll try this on Linux/x86 too. Comments appreciated! Especially on whether or not this is good enough to commit, or what's lacking. I get these errors after applying io-nio.patch then io-nio2.patch, re-running autogen.sh, and doing a clean build: 2. ERROR in /home/fitzsim/workspace/classpath/gnu/java/nio/channels/FileChannelImpl.java Whoops, yeah, I moved FileChannelImpl.java from gnu/java/nio/channels (it was the only class in that package) to gnu/java/nio; the patch probably doesn't reflect that. I thought I had it marked for delete locally... [...] -- 6. ERROR in /home/fitzsim/workspace/classpath/gnu/java/nio/KqueueSelectorImpl.java (at line 267) protected KqueueSelectionKeyImpl register(AbstractSelectableChannel channel, int interestOps, Object attachment) ^ ^^ The return type is incompatible with AbstractSelector.register(AbstractSelectableChannel, int, Object) Again, oops :-). Eclipse was using 1.5 semantics, I guess, where you can return a derived type instead of the declared type in a overridden method. The return type for that method should be 'SelectionKey.' I'm testing these patches to see if they fix the RMI problem I'm having (which may be unrelated): $ rmiregistry 3456 $ java -Djava.security.policy=/home/fitzsim/jin.patches/wideopen.policy examples.hello.HelloImpl java.net.SocketTimeoutException: Accept operation timed out [...] Were you aware of this problem? I think it was introduced by Mark's native layer merge. I wasn't aware of that problem, no. Since this patch rewrites accept() pretty much from scratch, then yeah, it may work in my version.
Re: [cp-patches] updated: IO, net, and NIO
Thomas Fitzsimmons wrote: Hi, Casey Marshall wrote: I wasn't aware of that problem, no. Since this patch rewrites accept() pretty much from scratch, then yeah, it may work in my version. Two more errors: 5. ERROR in /home/fitzsim/workspace/classpath/gnu/java/nio/FileChannelImpl.java (at line 128) this.ch = VMChannel.getVMChannel(this); The method getVMChannel(FileChannelImpl) is undefined for the type VMChannel -- 6. ERROR in /home/fitzsim/workspace/classpath/gnu/java/nio/FileChannelImpl.java (at line 161) this.ch = VMChannel.getVMChannel(this); The method getVMChannel(FileChannelImpl) is undefined for the type VMChannel ? Those calls don't appear in my local copy, or in the patch. (note, io-nio2.patch added nio/FileChannelImpl.java, but neither patch removed the original) Also, the patches are missing javanio.h. Noted (oops). I've updated the patches to fix these issues. cvs diff seems to refuse to add a removal diff to the patch, though.
Re: [cp-patches] PATCH: fix for JCL_GetRawData
Casey Marshall wrote: This is a better attempt at fixing the JCL_NewRawDataObject and JCL_GetRawData, which initializes the cached class, method, and field variables in JNI_OnLoad. This is potentially problematic, I suppose, because the jcl.lo object is linked directly to a number of Classpath's JNI libraries, which I suppose would mean that any such library couldn't have its own JNI_OnLoad. None of them do now, however (this sounds like it may be wrong, anyway: the JNI invocation interface docs seem to indicate that you need to have this function in your JNI library, which returns the JNI version you want to use, because otherwise the VM will assume you will be using the 1.1 interface; IOW we're using it wrong if we use JNI functions beyond 1.1. This sounds silly, though, and it works regardless). Comments on whether or not this will work are appreciated. 2006-09-09 Casey Marshall [EMAIL PROTECTED] * native/jni/classpath/jcl.c (JNI_OnLoad): new function. (JCL_NewRawDataObject): use pre-initialized Pointer variables. (JCL_GetRawData): likewise. Tested on Darwin/x86/jamvm, Linux/x86/cacao and Linux/x86/jamvm. Does this look OK to commit?
Re: [cp-patches] RFC: implement NetworkInterface
Here's a revised patch that uses getifaddrs. Works on Darwin with jamvm, I have not yet tested Linux. This still contains the same fix for jcl.c. I'll try to come up with a better solution that fixes the issue, but for now, if you want to try it on JamVM, you'll need this fix. ? native/jni/java-net/netif.c ? native/jni/java-net/netif.h Index: configure.ac === RCS file: /cvsroot/classpath/classpath/configure.ac,v retrieving revision 1.181 diff -u -r1.181 configure.ac --- configure.ac31 Aug 2006 19:56:03 - 1.181 +++ configure.ac9 Sep 2006 19:01:13 - @@ -373,12 +373,19 @@ fcntl \ mmap munmap mincore msync madvise getpagesize sysconf \ lstat readlink \ - ]) + getifaddrs]) LIBMAGIC= AC_CHECK_LIB(magic, magic_open, LIBMAGIC=-lmagic) AC_SUBST(LIBMAGIC) + AC_MSG_CHECKING([whether struct sockaddr_in6 is in netinet/in.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include netinet/in.h]], [[struct sockaddr_in6 addr6;]])], +[AC_DEFINE(HAVE_INET6, 1, + [Define if inet6 structures are defined in netinet/in.h.]) + AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no)]) + AC_HEADER_TIME AC_STRUCT_TM AC_STRUCT_TIMEZONE Index: include/java_net_VMNetworkInterface.h === RCS file: /cvsroot/classpath/classpath/include/java_net_VMNetworkInterface.h,v retrieving revision 1.1 diff -u -r1.1 java_net_VMNetworkInterface.h --- include/java_net_VMNetworkInterface.h 11 Apr 2005 18:58:38 - 1.1 +++ include/java_net_VMNetworkInterface.h 9 Sep 2006 19:01:13 - @@ -1,19 +1,29 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ - -#ifndef __java_net_VMNetworkInterface__ -#define __java_net_VMNetworkInterface__ - #include jni.h +/* Header for class java_net_VMNetworkInterface */ +#ifndef _Included_java_net_VMNetworkInterface +#define _Included_java_net_VMNetworkInterface #ifdef __cplusplus -extern C -{ +extern C { #endif - -JNIEXPORT jobject JNICALL Java_java_net_VMNetworkInterface_getInterfaces (JNIEnv *env, jclass); +/* + * Class: java_net_VMNetworkInterface + * Method:initIds + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_java_net_VMNetworkInterface_initIds + (JNIEnv *, jclass); + +/* + * Class: java_net_VMNetworkInterface + * Method:getVMInterfaces + * Signature: ()[Ljava/net/VMNetworkInterface; + */ +JNIEXPORT jobjectArray JNICALL Java_java_net_VMNetworkInterface_getVMInterfaces + (JNIEnv *, jclass); #ifdef __cplusplus } #endif - -#endif /* __java_net_VMNetworkInterface__ */ +#endif Index: java/net/NetworkInterface.java === RCS file: /cvsroot/classpath/classpath/java/net/NetworkInterface.java,v retrieving revision 1.18 diff -u -r1.18 NetworkInterface.java --- java/net/NetworkInterface.java 29 Aug 2006 08:25:15 - 1.18 +++ java/net/NetworkInterface.java 9 Sep 2006 19:01:14 - @@ -38,6 +38,8 @@ package java.net; +import gnu.classpath.SystemProperties; + import java.util.Collection; import java.util.Collections; import java.util.Enumeration; @@ -58,25 +60,13 @@ */ public final class NetworkInterface { - private String name; - private Vector inetAddresses; - - NetworkInterface(String name, InetAddress address) - { -this.name = name; -this.inetAddresses = new Vector(1, 1); -this.inetAddresses.add(address); - } + private final VMNetworkInterface netif; - NetworkInterface(String name, InetAddress[] addresses) + private NetworkInterface(VMNetworkInterface netif) { -this.name = name; -this.inetAddresses = new Vector(addresses.length, 1); - -for (int i = 0; i addresses.length; i++) - this.inetAddresses.add(addresses[i]); +this.netif = netif; } - + /** * Returns the name of the network interface * @@ -84,7 +74,7 @@ */ public String getName() { -return name; +return netif.name; } /** @@ -100,6 +90,7 @@ public Enumeration getInetAddresses() { SecurityManager s = System.getSecurityManager(); +Vector inetAddresses = new Vector(netif.addresses); if (s == null) return inetAddresses.elements(); @@ -131,7 +122,7 @@ */ public String getDisplayName() { -return name; +return netif.name; } /** @@ -148,15 +139,14 @@ public static NetworkInterface getByName(String name) throws SocketException { -for (Enumeration e = getNetworkInterfaces(); e.hasMoreElements();) +if (name == null) + throw new NullPointerException(); +VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces(); +for (int i = 0; i netifs.length; i++) { - NetworkInterface tmp = (NetworkInterface) e.nextElement(); - -
[cp-patches] PATCH: fix for JCL_GetRawData
This is a better attempt at fixing the JCL_NewRawDataObject and JCL_GetRawData, which initializes the cached class, method, and field variables in JNI_OnLoad. This is potentially problematic, I suppose, because the jcl.lo object is linked directly to a number of Classpath's JNI libraries, which I suppose would mean that any such library couldn't have its own JNI_OnLoad. None of them do now, however (this sounds like it may be wrong, anyway: the JNI invocation interface docs seem to indicate that you need to have this function in your JNI library, which returns the JNI version you want to use, because otherwise the VM will assume you will be using the 1.1 interface; IOW we're using it wrong if we use JNI functions beyond 1.1. This sounds silly, though, and it works regardless). Comments on whether or not this will work are appreciated. 2006-09-09 Casey Marshall [EMAIL PROTECTED] * native/jni/classpath/jcl.c (JNI_OnLoad): new function. (JCL_NewRawDataObject): use pre-initialized Pointer variables. (JCL_GetRawData): likewise. Thanks. ? native/jni/classpath/jcl_nstate.c ? native/jni/classpath/jcl_pointer.c ? native/jni/classpath/jcl_pointer.h Index: native/jni/classpath/jcl.c === RCS file: /cvsroot/classpath/classpath/native/jni/classpath/jcl.c,v retrieving revision 1.23 diff -u -r1.23 jcl.c --- native/jni/classpath/jcl.c 3 Apr 2006 14:03:12 - 1.23 +++ native/jni/classpath/jcl.c 10 Sep 2006 03:46:35 - @@ -48,6 +48,63 @@ #endif #endif +/* + * Cached Pointer class info. + */ +static jclass rawDataClass; +static jfieldID rawData_fid; +static jmethodID rawData_mid; + +/* + * JNI OnLoad constructor. + */ +jint +JNI_OnLoad (JavaVM *vm, void *reserved) +{ + JNIEnv *env; + + if ((*vm)-GetEnv (vm, env, JNI_VERSION_1_4) != JNI_OK) +{ + return JNI_VERSION_1_4; +} +#if SIZEOF_VOID_P == 8 + rawDataClass = (*env)-FindClass (env, gnu/classpath/Pointer64); + if (rawDataClass != NULL) +{ + jclass tmp = rawDataClass; + rawDataClass = (*env)-NewGlobalRef (env, rawDataClass); + (*env)-DeleteGlobalRef (env, tmp); +} + + if (rawDataClass != NULL) +{ + rawData_fid = (*env)-GetFieldID (env, rawDataClass, data, J); + rawData_mid = (*env)-GetMethodID (env, rawDataClass, init, (J)V); +} +#else +#if SIZEOF_VOID_P == 4 + rawDataClass = (*env)-FindClass (env, gnu/classpath/Pointer32); + if (rawDataClass != NULL) +{ + jclass tmp = rawDataClass; + rawDataClass = (*env)-NewGlobalRef (env, rawDataClass); + (*env)-DeleteGlobalRef (env, tmp); +} + + if (rawDataClass != NULL) +{ + rawData_fid = (*env)-GetFieldID (env, rawDataClass, data, I); + rawData_mid = (*env)-GetMethodID (env, rawDataClass, init, (I)V); +} +#else +#error Pointer size is not supported. +#endif /* SIZEOF_VOID_P == 4 */ +#endif /* SIZEOF_VOID_P == 8 */ + + return JNI_VERSION_1_4; +} + + JNIEXPORT void JNICALL JCL_ThrowException (JNIEnv * env, const char *className, const char *errMsg) { @@ -183,78 +240,17 @@ /* - * Build a Pointer object. The function caches the class type + * Build a Pointer object. */ -static jclass rawDataClass; -static jfieldID rawData_fid; -static jmethodID rawData_mid; - JNIEXPORT jobject JNICALL JCL_NewRawDataObject (JNIEnv * env, void *data) { - if (rawDataClass == NULL) + if (rawDataClass == NULL || rawData_mid == NULL) { - jclass tmp; -#if SIZEOF_VOID_P == 8 - rawDataClass = (*env)-FindClass (env, gnu/classpath/Pointer64); - if (rawDataClass == NULL) - { - JCL_ThrowException (env, java/lang/InternalError, - unable to find internal class); - return NULL; - } - - rawData_mid = (*env)-GetMethodID (env, rawDataClass, init, (J)V); - if (rawData_mid == NULL) - { - JCL_ThrowException (env, java/lang/InternalError, - unable to find internal constructor); - return NULL; - } - - rawData_fid = (*env)-GetFieldID (env, rawDataClass, data, J); - if (rawData_fid == NULL) - { - JCL_ThrowException (env, java/lang/InternalError, - unable to find internal field); - return NULL; - } -#else - rawDataClass = (*env)-FindClass (env, gnu/classpath/Pointer32); - if (rawDataClass == NULL) - { - JCL_ThrowException (env, java/lang/InternalError, - unable to find internal class); - return NULL; - } - - rawData_mid = (*env)-GetMethodID (env, rawDataClass, init, (I)V); - if (rawData_mid == NULL) - { - JCL_ThrowException (env, java/lang/InternalError, - unable to find internal constructor); - return NULL; - } - - rawData_fid = (*env)-GetFieldID (env, rawDataClass, data, I); - if (rawData_fid == NULL
[cp-patches] RFC: implement NetworkInterface
I was disappointed to find that NetworkInterface doesn't have a default implementation in Classpath; I put together the attached version. There are apparently a bunch of ways to get this data. This version is based on the 'sysctl' one described in W. Richard Stevens' book, UNIX Network Programming. This seems to work fine on Darwin; I'll try it on Linux when I get a chance. This version will return IPv6 addresses, if your system supports it. I've also changed some of the RawData functions in jcl.c. JCL_GetRawData depends on the static variable `rawData_fid' being initialized, which only gets set in `JCL_NewRawDataObject.' On jamvm, the JNI function `NewDirectBuffer' doesn't call `JCL_NewRawDataObject,' meaning these fields aren't initialized. The current code isn't thread safe, either, so here I've just removed the caching for now (the caching code creates a new global reference, so it is important for this to be thread safe). Removing the caching may be a performance hit. 2006-09-07 Casey Marshall [EMAIL PROTECTED] * configure.ac: add check for `sysctl;' add check for IPv6 support. * include/java_net_VMNetworkInterface.h: regenerated. * java/net/NetworkInterface.java (name, inetAddresses): removed. (netif): new field. (init, init): removed. (init): new, private constructor. (getName): delegate to VMNetworkInterface. (getInetAddresses): create inetAddresses Vector here. (getByName): iterate over the list of VMNetworkInterface objects. (getByAddress): likewise. (condense): removed. (getNetworkInterfaces): use `VMNetworkInterface.getVMInterfaces.' (equals): compare fields in VMNetworkInterface. (hashCode): get hash codes from VMNetworkInterface fields. (toString): use a StringBuffer. * native/jni/classpath/jcl.c (rawDataClass, rawData_fid, rawData_mid): removed. (JCL_NewRawDataObject): make the above local; don't create a global reference. (JCL_GetRawData): get the field ID here. * native/jni/java-net/Makefile.am (libjavanet_la_SOURCES): add netif.c and netif.h. * native/jni/java-net/java_net_VMNetworkInterface.c (java_net_VMNetworkInterface_init, java_net_VMNetworkInterface_addAddress): new static variables. (Java_java_net_VMNetworkInterface_initIds): new function. (Java_java_net_VMNetworkInterface_getInterfaces): removed. (Java_java_net_VMNetworkInterface_getVMInterfaces): new function. * native/jni/java-net/netif.c: new file. * native/jni/java-net/netif.h: new file. * vm/reference/java/net/VMNetworkInterface.java (name, addresses): new fields. (clinit): call `initIds'. (initIds): new method. (getInterfaces): removed. (getVMInterfaces, addAddress): new methods. ? native/jni/java-net/netif.c ? native/jni/java-net/netif.h Index: configure.ac === RCS file: /cvsroot/classpath/classpath/configure.ac,v retrieving revision 1.181 diff -u -r1.181 configure.ac --- configure.ac31 Aug 2006 19:56:03 - 1.181 +++ configure.ac8 Sep 2006 06:31:12 - @@ -373,12 +373,19 @@ fcntl \ mmap munmap mincore msync madvise getpagesize sysconf \ lstat readlink \ - ]) + sysctl]) LIBMAGIC= AC_CHECK_LIB(magic, magic_open, LIBMAGIC=-lmagic) AC_SUBST(LIBMAGIC) + AC_MSG_CHECKING([whether struct sockaddr_in6 is in netinet/in.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include netinet/in.h]], [[struct sockaddr_in6 addr6;]])], +[AC_DEFINE(HAVE_INET6, 1, + [Define if inet6 structures are defined in netinet/in.h.]) + AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no)]) + AC_HEADER_TIME AC_STRUCT_TM AC_STRUCT_TIMEZONE Index: include/java_net_VMNetworkInterface.h === RCS file: /cvsroot/classpath/classpath/include/java_net_VMNetworkInterface.h,v retrieving revision 1.1 diff -u -r1.1 java_net_VMNetworkInterface.h --- include/java_net_VMNetworkInterface.h 11 Apr 2005 18:58:38 - 1.1 +++ include/java_net_VMNetworkInterface.h 8 Sep 2006 06:31:12 - @@ -1,19 +1,29 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ - -#ifndef __java_net_VMNetworkInterface__ -#define __java_net_VMNetworkInterface__ - #include jni.h +/* Header for class java_net_VMNetworkInterface */ +#ifndef _Included_java_net_VMNetworkInterface +#define _Included_java_net_VMNetworkInterface #ifdef __cplusplus -extern C -{ +extern C { #endif - -JNIEXPORT jobject JNICALL Java_java_net_VMNetworkInterface_getInterfaces (JNIEnv *env, jclass); +/* + * Class: java_net_VMNetworkInterface + * Method:initIds + * Signature
Re: [cp-patches] RFC: implement NetworkInterface
Tom Tromey wrote: Casey == Casey Marshall [EMAIL PROTECTED] writes: Casey There are apparently a bunch of ways to get this data. This version is Casey based on the 'sysctl' one described in W. Richard Stevens' book, UNIX Casey Network Programming. This seems to work fine on Darwin; I'll try it on Casey Linux when I get a chance. The sysctl man page on linux says: The object names vary between kernel versions. THIS MAKES THIS SYSTEM CALL WORTHLESS FOR APPLICATIONS. ... not exactly confidence inspiring, but perhaps the man page is not really correct. FWIW in libgcj we use getifaddrs if it is available (this is a nice, easy-to-use API) or some horrible ioctls (SIOCGIFCONF and SIOCGIFADDR) otherwise. We've also got a Windows port you could lift... if you had a way to build it I suppose. Sigh. You're right. The sane sysctl looks like a BSD thing. If Darwin has getifaddrs, I'd prefer we use it. The ioctl stuff could probably just be ignored, I'd imagine it is more of a legacy system thing. getifaddrs is supported on Darwin, too. I'll use that. Casey I've also changed some of the RawData functions in jcl.c. A separate patch here would be good... OK. Casey JCL_GetRawData depends on the static variable `rawData_fid' being Casey initialized, which only gets set in `JCL_NewRawDataObject.' The library should either initialize itself or we should require VMs using it to initialize it. We should initialize this properly ourselves, and not make the VM do it. JCL is Classpath-internal, so it should work and be portable. Casey* java/net/NetworkInterface.java (name, inetAddresses): removed. Casey(netif): new field. This change is a bit of a pain since it means existing users all have to be updated. If you think it is really important, we should still do it, of course ... but I'd prefer not to if possible. The point of this was to try and encapsulate data read/modified by native code in it's own class. If we don't want to do this, that's fine. I'll come up with an alternative. If we do change it, this has to be documented in NEWS, as it is a VM interface change. Yup. Thanks.
Re: [cp-patches] RFC: PR Classpath/28664 - GNU MP based BigInteger(compressed)
Raif S. Naffah wrote: + with GMP969ms. - without GMP 11,718ms. What VM?
Re: [cp-patches] RFC: PR Classpath/28664 - GNU MP based BigInteger (compressed)
Raif S. Naffah wrote: hello all, the attached patch adds support for GNU MP in BigInteger if/when configured. 2006-09-03 Raif S. Naffah [EMAIL PROTECTED] PR Classpath/28664 * INSTALL: Added documentation about GNU MP. * configure.ac: Add support for configuring GNU MP. * native/jni/Makefile.am: Include java-math directory if required. * native/jni/java_math/.cvsignore: New file. * native/jni/java_math/Makefile.am: Likewise. * native/jni/java_math/java_math_BigInteger.c: Likewise. * native/jni/java_math: New folder. * include/java_math_BigInteger.h: New file. * java/math/BigInteger.java: Added support for native methods. * gnu/classpath/Configuration.java.in (WANT_NATIVE_BIG_INTEGER): New field. this was tested with current CVS head and cacao trunk (updated to revision 5285). Mauve tests for BigInteger, and crypto classes (gnu.testlet.java.security and gnu.testlet.javax.crypto) all pass with cacao but systematically, almost half of them, fail with jamvm (latest CVS head). a couple of more Mauve tests will be added soon, and another couple will be updated. Mark, would you be kind as to have a look at this before i commit? finally, thanks for Mark and Dalibor for their help and advice. Some comments: +static void +_throw (JNIEnv *env, const char *exception, const char *msg) +{ + jclass _theclass = (*env)-FindClass (env, exception); + TRACE(begin); + if (! _theclass) +{ + (*env)-FatalError (env, exception class not found); +} + (*env)-ThrowNew (env, _theclass, msg); + TRACE(end); +} You should use JCL_ThrowException. + * a. Pass NULLs to the mp_set_memory_functions implying that GMP should use + *malloc, realloc and free for memory allocation, and if they fail GMP + *will print a message to the standard error output and terminates the + *program. Should you use JCL_malloc, etc. there? Also, it's a little odd that you're using JNI_OnLoad, and aren't just calling some native init method when the BigInteger class is loaded. + For building, and using a GNU MP based implementation of the + java.math.BigInteger class, you will need, at least version 3.1 + of GMP. http://swox.com/gmp/ That's bad grammar. If you omit the first and third comma it sounds a little better. As far as the implementation (and the comments about finalize, etc. elsewhere in this thread) I wonder if it's possible here to use a direct ByteBuffer to store your native state (I guess GMP is allocating structures behind the scenes, and is sticking it into your mpz_ptr; BUT, BigInteger is immutable, so you presumably know how large it is), then you pass that ByteBuffer to all native methods, which pull out the native pointer. I'm really a fan of this approach, which I used to some success in my kqueue Selector implementation (which hasn't been committed yet, unfortunately), and I do encourage others to try it. The benefits of doing it this way are legion: - The GC will take care of freeing the native state for you. - You don't need to finalize anything, and don't need to synchronize. - Your native methods can be static, and what's more, they can be in an entirely different class, so other VM implementors won't have to deal with native methods being in java.math directly. - You need exactly one JNI function call (GetDirectBufferAddress) and no (or possibly little) reflection. - You can debug your native state in Javaland, if you feel like it. It makes your usage of JNI *much* more careful and simple. Thanks.
Re: [cp-patches] FYI: new utility class IntegerUtil
Raif S. Naffah wrote: hello all, the attached patch --already committed-- adds Integer related utility methods to: a. cache Integer.valueOf(String) results in a LRU of 100 places organised by access order, b. simulate the version 5 Integer.valueOf(int) method, so client code can run on a version 1.4 of the Java class library. a new Mauve test TestOfIntegerUtil (in gnu.testlet.gnu.java.security.util) has been added. 2006-07-22 Raif S. Naffah [EMAIL PROTECTED] * gnu/java/security/util/IntegerUtil.java: New file. You didn't update all the classes that you changed in your patch that replaced 'new Integer' with 'Integer.valueOf'. In fact, I see some classes were changed (gnu.java.security.util.Sequence) but aren't mentioned in the changelog [1]. In fact, did you change any of the classes you originally modified to use this? 1. http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/security/util/Sequence.java?rev=1.2root=classpathview=markup
Re: [cp-patches] FYI: LocalSocket fixlets
Roman Kennke wrote: This fixes two little issues that I had when porting the LocalSocketImpl to JamaicaVM: - It only loads the library dynamically when actually supported by the runtime. - It includes config.h unconditionally. Actually it doesn't seem to make sense to do: #if HAVE_CONFIG_H #include config.h #endif since HAVE_CONFIG_H is defined in config.h. You should leave the #if around the #include (actually, it should be #ifdef, I think). You'll notice that HAVE_CONFIG_H is defined on the gcc command line in Classpath; autoconf/autoheader adds that to your compile-time flags so you know when you can include config.h. If it's biting you that HAVE_CONFIG_H isn't defined, and you need to include config.h, you should define it, then ;-) I think this is the autoconf way: you don't #include or use something unless you have a HAVE_ macro telling you it's OK. I mean, you could very well just use gcc flags at compile time *instead* of config.h; the latter just makes it easy to have lots of conditionals. I also think this is typical GNU practice, so please leave the conditionals in. Thanks.
Re: [cp-patches] RFC: File/VMFile improvement
Roman Kennke wrote: Hi there again, What about this pending patch? I didn't quite understand the discussion around it. IMO the file handling is very platform dependend and while we could handle this generically, I find this path very inconvenient, as it clutters the code, where it could be easy, and it certainly isn't very good for efficiency. I agree that this is not necessarily VM dependent, but instead platform dependend? But I don't think that we should introduce some kind of platform-layer that complements the VM layer in some way. As Jeroen already pointed out, often times the VM is somewhat tied to the platform(s) it supports and thus can just as well provide a reasonable implementation of file handling. Sorry, that was kind of a bikeshed issue. VM-vs-platform isn't *that* big a deal, it just feels clumsy, and has been used as an I don't understand this umbrella in the past. As for the VMBlahSocketImpl, I would very much like to have this mess cleaned up (I know, I introduced this in the first place). I came to think of that we don't really need this anyway, as the specs already have a way of abstracting this stuff out (by defining the SocketImpl abstract classes) and we simply added another unnecessary layer here. This is true, and it's the same with java.nio (it's essentially a service provider interface through the SelectorProvider class). There is *some* value in isolating these platform-specific bits as much as possible (and keeping them, and the amount of JNI code, to a minimum!), and making porting Classpath a low-barrier-to-entry. What, if any, performance tradeoffs there are is a good question, however. So may I commit this change to the VMFile class for now? Or should we go another way of splitting out platform dependend stuff? Sorry for not looking at it. The patch looks reasonable to me. Real code is always preferable to me bickering about vaporware :-)
Re: [cp-patches] RFC: refactor (and finish) IO and NIO
Jeroen Frijters wrote: Casey Marshall wrote: What I'd like people to look at and comment on specifically are the changes to gnu.java.nio.VMChannel and gnu.java.net.VMPlainSocketImpl, for opinions on how well these classes (the public methods) help abstract away platform-specific code. Thanks. I like the idea of the patch, but I have quite a few comments about the current implementation. As a reminder: Please don't take my directness the wrong way, English is not my native language and I'm rather blunt, even for a Dutchman. These are all excellent points! Thanks for looking at this. Here are most of them: - The NativeFD interface should have a better name (e.g. something like VMChannelOwner). Agreed. I can't think of a good adjective for a name, though (but VMChannelOwner is fine). - I don't like the fact that you're introducing allocation in virtually every I/O path. Hmm, I don't think I'm doing that as much for Channels, where performance is arguably more important. - Why vmch.getNativeFD().close(); instead of vmch.close();? No reason. I wanted the `close' bit to be tied to the NativeFD object, but putting the API close call in the containing class is fine. - Most classes should not have a finalize method, only VMChannel should have a finalize method. Yeah, true (all finalize methods did exist previously; I just changed what they did instead of removing them). - All valid socket options should be delegated to impl (and if any aren't yet implemented, the impl should throw the UnsupportedOperationException). Yes. - Method naming could be better (return ch.getVMChannel().getNativeFD().getNativeFD();). Agreed :-) - Instead of changing FileInputStream/FileOutputStream/RandomAccessFile, FileChannelImpl should accommodate them. I'm not sure what you mean by this. - PlainSocketImpl uses ByteBuffer.allocateDirect to allocate the two single byte buffers (oneByteRead and oneByteWrite, which aren't used BTW), I'd like to see the decision to use allocate vs. allocateDirect delegated to VMPlainSocketImpl. (For me allocateDirect is actually less efficient in this case). Yeah, that was some cruft for an idea that didn't pan out. Also, I typicaly used allocateDirect because I (mistakenly) thought that the scatter/gather IO methods required direct buffers (they don't). I didn't correct this everywhere. And, our ByteBuffers in general suffer from some performance issues. - PlainSocketImpl.connect should simply call impl.connect(address,timeout) which in turn calls channel.connect(address,timeout), the decision how to implement the timeout should be in the VM layer. Good point. - PlainSocketImpl.write(byte[],int,int) implementation is unacceptable. OK. I don't think that method is needed any more, though. The output stream calls on the channel directly. Thanks for the feedback!
Re: [cp-patches] RFC: refactor (and finish) IO and NIO
Casey Marshall wrote: Jeroen Frijters wrote: - PlainSocketImpl.connect should simply call impl.connect(address,timeout) which in turn calls channel.connect(address,timeout), the decision how to implement the timeout should be in the VM layer. Good point. The current version (setting SO_TIMEOUT) also won't work in practice. That method sets the SO_RCVTIMEO socket option, not SO_SNDTIMEO, which is the one that should be set, AFAICT. I don't know if that actually works, though. Stevens says to use SIGALRM for this, which I doubt will work here; others recommend putting the socket into nonblocking mode, then use select.
Re: [cp-patches] RFC: File/VMFile improvement
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jeroen Frijters wrote: Casey Marshall wrote: Tom Tromey wrote: It seems to me that this is an area we haven't handled very well: this isn't really a VM thing per se -- the code could very well be written in pure java -- but rather a platform thing. I agree that adding special cases in File just makes the code uglier and uglier. But, we could delegate to a pure java platform class, with instances for posixy, Windows, Windows CE, etc, and share the code across all VMs. We do something vaguely similar to this in libgcj (though in the specific case of File we put the platform stuff in native code). FWIW I agree. Some of us were chatting about this on IRC, and not only are these VM interfaces more often than not platform interfaces (or with some things, all they rely on is JNI and standard C), but they do lead to performance hits (witness our direct ByteBuffer). I think putting some design thought into this is a good idea, because right now I don't think we have any clear idea about what the scope or purpose of VM/platform interfaces are. Right now, it looks like it's just an ad-hoc catch-all for anything that can't be done in pure Java -- you slap a VM class on it, and hack up the core class. I disagree. In most cases the VM decides what platforms to support and how to do this, so it does make some sense to move this stuff into the VM interface. This combined with the fact that native methods are very inconvenient for some VMs (like IKVM), we decided to add this extra indirection layer where the VM can decide to do things differently. OK. But I could argue back that VMs for whom native methods don't work are broken as far a Java goes. I think you're saying that because platform details, like how files and sockets work, are easier for you to implement in the VM layer, that they're necessarily VM-specific, and not platform-specific. I couldn't disagree more with that. There's also no rule saying that you have to use Classpath's version of a class in your VM/system. If we can set things up such that as long as you implement these classes *to the Java specification,* everything works, you can have whatever implementation suits your system, and just load that class first. I realise that for gcj people it may look like there is a significant difference between (e.g.) VMFile and VMThread, but other VMs replace both these classes. Yeah, if I were writing a VM for Windows, I'd re-implement both. But, VMThread would necessarily be tied to the VM's internals; VMFile would be tied to how Windows handles files, having little to do with the VM itself. BTW, if there are specific cases (like ByteBuffer you mention), I'm more than willing to discuss alternatives to find a better alternative to suites everyone. I think that in many cases the VM interface design suffers from the fact that not enough VM implementers participate in the design. ByteBuffer (and Channels and Selectors -- that is, things that are basically created with factory methods and service providers) are a little different, because we can, e.g., control what version we use at runtime with system properties. So posixy systems can return a fast, native implementation, and other systems can return their own implementation. If we keep the VM* interface thing, I think a better design is to stop passing the core class to a static VM method, with the native state inside the core class, and just make these VM classes instance classes, with the native state associated with the instance. An example I'm thinking of is VMPlainSocketImpl. PlainSocketImpl has an int field for the native file descriptor (and that makes just plain no sense, either way), and passes itself to VMPlainSocketImpl methods, which rips the descriptor integer out of that instance. I think it's better to make VMPlainSocketImpl an instance class, and keep the native state in that instance; in our default implementation, this would be an integer file descriptor, and we'd have method pairs like so in the VM class: public void vmMethod(args...) throws IOException { vmMethod(native_fd, args...); } private static native void vmMethod(int native_fd, args...) throws... So the *interface* for the VM class is the public instance method, and is the only one a VM writer needs to implement. Our default implementation then just implements the function in the obvious, fast way for POSIX. Maybe you can explain why passing an object to a static method makes more sense than that (I can't see how; all it adds is a litany of JNI calls to *every* method call). -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBROLRteRILCRAfKHCAQK1dAf/W2jQgbJ1h3Ru9+z3unRfAylRMp308vpk Dj5DCYfxHzQUnoYN4Dd+VeCmxrenaTxzj+WBcbeJZC1E5PW775q3WhKUOLgsrJ/z SbeSq6VGarUYx+GQ3apTy0vrPtB+apcMY2scPJ21iyiGrK+9AsQ+S6b1CHDUk/K1 hcoxc7GxaHtYFulkyb8DDgYb
Re: [cp-patches] RFC: File/VMFile improvement
Jeroen Frijters wrote: Hi Casey, I just about exploded when I read the first part of your message ;-) But at the end of your message I discovered that we completely misunderstood each other and that we agree much more than we disagree. Yeah, in the end we probably do agree more than we think ;-) I was being on the aggressive side in that email, but not hurtfully so. Really that part is mostly bikeshed material (i.e., what's VM and what's platform, and the terminology is a minefield of misunderstanding), and I don't see much disagreement on the conclusion -- that some of the VM interfaces are a mess, and are inefficient, and that something like I've proposed may be a good solution. I'm still working on a patch to fix this for socket NIO (I posted a preliminary version to this list). Thanks.
Re: [cp-patches] RFC: File/VMFile improvement
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Tom Tromey wrote: Roman == Roman Kennke [EMAIL PROTECTED] writes: Roman we are having problems here with java.io.File on Windows CE. Which Roman handles files different again than other Windows and of course Roman different than Unix. [...] Roman Maybe we should get rid of all the special casing anyway and provide a Roman default straightforward impl for Posixy systems, for the sake of Roman efficiency and cleanness. It seems to me that this is an area we haven't handled very well: this isn't really a VM thing per se -- the code could very well be written in pure java -- but rather a platform thing. I agree that adding special cases in File just makes the code uglier and uglier. But, we could delegate to a pure java platform class, with instances for posixy, Windows, Windows CE, etc, and share the code across all VMs. We do something vaguely similar to this in libgcj (though in the specific case of File we put the platform stuff in native code). FWIW I agree. Some of us were chatting about this on IRC, and not only are these VM interfaces more often than not platform interfaces (or with some things, all they rely on is JNI and standard C), but they do lead to performance hits (witness our direct ByteBuffer). I think putting some design thought into this is a good idea, because right now I don't think we have any clear idea about what the scope or purpose of VM/platform interfaces are. Right now, it looks like it's just an ad-hoc catch-all for anything that can't be done in pure Java -- you slap a VM class on it, and hack up the core class. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBROIpJuRILCRAfKHCAQIX5wf/aog1Jk+M1HNBKd7HZ6vzciTuPAynvlZ+ U+v7fvGI4FWaoCMUidB3rwov+gJhTXFpJpBy7ytGRExgpaJNp2Mp3kDpUJiInwYs pGh4rmzPvEd8dgkRyL7e4ccBF9ze7Ix7DzhXsldgNypOBDN+Bs7e1A9PjClnxQN8 t84Ii6YKeiifusAPRtgkmsS1wKF4PbCZ7YOdtT/BI6PfaERpgI4V/EnKASwx5Zp2 Z43NGTi/vvRb+qeOFbfhs8XA41EK5eb7ODDD6+W88PKcPUGLgaDlWHCP92XZdrS2 I/K4Ca9vluGs94WcMaflz7dFv9ofko4s9LmygqTIY+I8BKaXz2jTTw== =V2jF -END PGP SIGNATURE-
Re: [cp-patches] Merge NATIVE-LAYER to HEAD
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Guilhem Lavaux wrote: Hi, Here is a patch to merge NATIVE-LAYER branch to HEAD. I expect that the new code will have some troubles to compile on some random OS different from linux but hopefully it is sufficiently flexible to be Yeah, it won't compile on darwin/x86: - - gcc -DHAVE_CONFIG_H -I. -I../../../../native/jni/native-lib - -I../../../include -I../../../../include - -I../../../../native/jni/classpath -I../../../../native/jni/native-lib - -pedantic -W -Wall -Wmissing-declarations -Wwrite-strings - -Wmissing-prototypes -Wno-long-long -Wstrict-prototypes -g -O2 -MT cpnet.lo -MD -MP -MF .deps/cpnet.Tpo -c ../../../../native/jni/native-lib/cpnet.c -fno-common -DPIC -o .libs/cpnet.o - - ../../../../native/jni/native-lib/cpnet.c: In function 'cpnet_connect': - - ../../../../native/jni/native-lib/cpnet.c:183: warning: unused variable 'theaddr' - - ../../../../native/jni/native-lib/cpnet.c: In function 'cpnet_send': - - ../../../../native/jni/native-lib/cpnet.c:252: error: 'MSG_NOSIGNAL' undeclared (first use in this function) - - ../../../../native/jni/native-lib/cpnet.c:252: error: (Each undeclared identifier is reported only once - - ../../../../native/jni/native-lib/cpnet.c:252: error: for each function it appears in.) - - ../../../../native/jni/native-lib/cpnet.c: In function 'cpnet_sendTo': - - ../../../../native/jni/native-lib/cpnet.c:268: error: 'MSG_NOSIGNAL' undeclared (first use in this function) - - ../../../../native/jni/native-lib/cpnet.c: In function 'cpnet_getHostByName': - - ../../../../native/jni/native-lib/cpnet.c:603: warning: implicit declaration of function 'gethostbyname_r' autoconfiscated. I have checked there is one less regression on my system (I have not tested the AWT part because this system is a bit out of date and I could not compile the peers but I have not touched anything in that part so there should not be any regression). At the moment the ChangeLog is not yet merged. The branch changelog is still held in ChangeLog.native (Mark what to do with this ?). I would like some of you test this on a linux workstation and see if it works ok. I will leave for (real !) vacations tomorrow so I may not be joinable. Casey can you take this in charge if I am not responsive ? You told me you can help... I've been hacking on our NIO stuff a bit, and I will need to modify our java.net code, too. I'd like to do those modifications after this goes in. In general I'll say that the approach looks pretty good. I'd prefer that we stick closer to a POSIX API, and make the cp* functions just simple wrappers where they need to be (as in: blocking syscalls). I don't have a Linux machine to test this on right now, though. It is probably OK to commit this now, then fix the issues on darwin (et al) in CVS. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBRODsGeRILCRAfKHCAQL9TggAtCy675oOCUPz3x8BdOXy1i8q62aI8Twb 3qSen0TD8HKrhpv/RT5yVSl8rq1oVXxByhyI7C4kQFsZY+4DlUmMuBK9tyQBACSx tdBTTkPAti3Q16it+HZeuFOgGLFaLuGaGox09R/ke3ZOU/1b6ShNMix6W4bcoWID +UEMvwE5AEblPAXvB5YIhPKNHhPv45DP8rEVdFaDh9SMUP7v4+08qeLVuRLC+LhW OHF5clPPupdQEfFWzt/PUfobZzY/s7raJRkg7SIjYZA7Owmo8r1WZJ77QG89SKmI 7CIPFXbvvAvh3KHFxzBsmgAMsV4Vzt6N9thg9eBmR5/YKHIeAt1vQA== =mXZB -END PGP SIGNATURE-
[cp-patches] Re: RFC: merge ssl-nio-branch into generics-branch
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Casey Marshall wrote: Hi all. The ssl-nio work is complete enough to the point where it can be merged into the generics branch. Now that 0.92 has been released, this is a good time to do that merge. OK, I've done this. The generics-branch now contains a new JSSE provider, the new javax/net/ssl classes and changes to existing ones, and a few little additions for 1.5 support in security and crypto. You shouldn't be able to tell the difference, if you use URLConnection with https URLs, or are using SSLSocket directly. If you think you spot any bugs, though, please let me know about them! Thanks a lot. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBROD/UuRILCRAfKHCAQJ03wgAr0DIxf0ZiBUA/kIJ/esh6WnWsaqjCT7Z a3mdCVVT1xtoWmCUwgVRnR/5qG1BSZ5z+6x4u+SIKJ0f+CI+THGnhgJTsvI3Yu63 RB3PvZ/Q9jkWCoJLuJWy7OD3EXc97fpcpSJFTlMrJTTAGZLZg7S9/eR3IoJ70M57 HzFfki52U1U4LiTZKhrRfh0WYlPuOmVe/7/l6NIi1YmY6Vkr6xZGIzYuWQGfTC0I 2WR+/0AJxf/ieXRKjd1tYaJfx5723j7sXZyohBNzNl0iusyyDwYuIktdBybWhFuM hqgO8dvJHPgInKEonAxZinZQFfPMDSXAbFQEjxFwZ9Vez+uSrPYSUQ== =UWa+ -END PGP SIGNATURE-
[cp-patches] RFC: merge ssl-nio-branch into generics-branch
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Hi all. The ssl-nio work is complete enough to the point where it can be merged into the generics branch. Now that 0.92 has been released, this is a good time to do that merge. I've accomplished three of the four goals I set out on this project, which were [1]: - - 1. That the SSL library in GNU Classpath be rewritten to use the - - NIO model of the JSSE (that is, to write an implementation of the - - SSLEngine class). - - - - 2. That the blocking-IO SSL classes in GNU Classpath be rewritten - - to use the NIO classes. - - - - 3. That a complete unit test suite be written, which exercises the - - library with both partial and complete sample SSL connections. These - - tests should be integrated into the Mauve test suite (see - - http://sourceware.org/mauve/). This patch not only represents an implementation of the new SSL APIs introduced in Java 1.5, but additionally adds support for TLSv1.1 (the newest version of the protocol) and pre-shared key ciphersuites. The code is also, in my opinion, better written and easier to hack on than the original was. The tests have already been added to Mauve, and comprise a little over 100 tests that exercise nearly all cipher suites, using all protocol versions. I haven't gotten to the fourth, which I marked as optional anyway: - - 4. (Optional, if there is time) That we augment a free Java servlet - - container (such as GNU Gumdrop) as a test-bed for this library, set - - up such an instance on a public web server, and run some performance - - and scalability tests on this server. This is largely because Classpath's socket NIO is still too immature. I'm actively working on fixing that now, however. Once NIO is in good enough shape we can look at modifying Gumdrop to support SSL. The patch to do the merge is here: http://metastatic.org/source/ssl-nio-merge.patch.gz (the patch is over 1M uncompressed, and compressed, is 175K! So I'm not attaching it to this message) Unless there are any issues with this, I'll try to commit the patch this weekend. Thanks! 1. http://code.google.com/soc/gnu/appinfo.html?csaid=3F1821EB717AF23 -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBRN06IeRILCRAfKHCAQLS9wgAiHT3VB4uzgIGbn8Zt621DhIYuSWxI65t VT7uUoadMheAgPtVi2U9pAVzH7F5g3b7qqOFWS7e7Tq0IjE5m59c58gkEpB7rc42 jbv3zoy2cf3gNAmyI/TU0mMIYsT/nQ7wyTQTquIIQCM9qaF+mvyxE+VCgoxZTcfd PfSZQ/aoU5enSBPTpNbjTawll4rSG8t89ctpKe0IY7k1laKT8TMBoF27J+++kLrv NT299aNlYeB4+VpaHyc+BaXAH9lVGnsLR83iRwR998nlNBAHKNyZZhK3luj4H2t5 QvbqjKFnwHD/C+HSN+rsvtqH/3A0REdBQCBu5WMjQQ3Sh7K+2IrGWw== =gUWE -END PGP SIGNATURE-
Re: [cp-patches] RFC: refactoring gnu.java.nio and kqueue Selectors
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jeroen Frijters wrote: Tom Tromey wrote: Casey - Adds a NativeFD interface to all our Channel implementations that Casey returns the native file descriptor integer. The plan here would be that Casey a Selector implementation could work generically given that you register Casey a Channel that implements NativeFD. I think this is the only problematic bit. AIUI we've been careful until now to keep the 'fd == int' identity hidden in the VM layer. That makes it all a bit more palatable to VMs on non-posixy platforms; IKVM comes to mind. Yeah, in general int handles aren't great for me, but in this case I'm not convinced that it's worthwhile to design a more abstract VM layer. Sun already designed these APIs with a provider model (like the regular sockets) and like the regular sockets I just replaced all of the *Impl classes (although for nio I also had to replace some other classes, which wasn't ideal I guess.) One small point regarding this though, I think it's better to move around references to NativeFD and do the getNativeFD call that returns the int as late as possible (i.e. close to the native method invocation). That will at least make it easier to replace NativeFD with another class, should anyone want to do so. And it doesn't hurt perf or make the code any less clear (arguably more clear). On reflection, it actually seems like a better idea to augment VMChannel for this purpose (and refactor VMPlainSocketImpl) instead. Right now VMChannel takes a Channel object, and extracts the native file descriptor integer, and uses it internally. Instead, each Channel object could just create a VMChannel instance, delegate its method calls to it, and in our RI we'll use native FD integers under the hood. Some of the methods I was adding to VMChannel almost support this, anyway, like this: public int accept() throws IOException { return accept(nfd.getNativeFD()); } public static native int accept(int native_fd) throws IOException; We could instead make accept() return a new VMChannel, make the native method private, and in our reference implementation, use an integer native file descriptor. Most of the methods in VMChannel support this at least partially -- there is a plain call that doesn't use any descriptor integer, and a call that takes a FD int as an argument, and the former passes a private integer instance variable to the latter. We'd just need to make the FD ones private in the RI. Then we can add a getNativeFD() call to VMChannel, that platform specific code, like the kqueue Selector, can call. VMs that don't use integers as file descriptors can then throw UnsupportedOperationException for that method. Does this sound like it will work? I don't know if we usually define VM classes as classes to be instantiated, instead of being all static methods, but I can't think of any drawback of doing that. Thanks. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBRNhCkeRILCRAfKHCAQLWQgf/bl7TSQsJZu2IxNa2FmK+cUxbl2ETCGYR WxjS1tWPc+NnaWkIfeK9YyqPZOT4HE5n4r+e9ftdQb+uc1bY9C+9WhS3IGEHCGNu RjAUprE1fFUTWhgmUAHtDCbj6isMXuwCdXvAmbreeSyIMWJaApCXlZTVZa+RkW7M cqNBw5CxUhSmgA+/7dQUiXr5tMf8QfI9ZugQKHjCysLwK7txjN2SRDWfTeMwAXgF mV+puf7Iep2BJph8DInQ90aReAddsyAugLoZdD+ddlp2RjyIVNMkxfIvjH4n18Pl fTsg0SVarIbHR+ck/T6oWtIkkITH4O4X69ZINqihnpJuq6Sq5VSLJg== =MgZn -END PGP SIGNATURE-
Re: [cp-patches] RFC: refactoring gnu.java.nio and kqueue Selectors
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Tom Tromey wrote: Thanks for the feedback! Casey - Adds a NativeFD interface to all our Channel implementations that Casey returns the native file descriptor integer. The plan here would be that Casey a Selector implementation could work generically given that you register Casey a Channel that implements NativeFD. I think this is the only problematic bit. AIUI we've been careful until now to keep the 'fd == int' identity hidden in the VM layer. That makes it all a bit more palatable to VMs on non-posixy platforms; IKVM comes to mind. I'm not convinced that's such an issue, actually. File descriptor integers are just tokens, which identify some open resource. Mapping an int to some platform specific resource shouldn't be that hard. Using an int to identify these resources makes the JNI side much easier to write, because it requires zero JNI calls (which are a mess) to access that resource. Doing an int-to-VM-object mapping shouldn't be that hard for any VM, and shouldn't introduce too much overhead. This would admittedly be optimizing the whole design to fit a POSIX/JNI back end. If that's unpalatable, we can investigate using something else, but personally, I think optimizing the design for JNI and C on GNU/Linux is worthwhile. As is making our JNI code as simple as possible, because debugging it can be very difficult. I'd appreciate hearing opinions on this, of course. Casey This patch also adds a Selector based on kqueue/kevent, the event Casey notification mechanism on Mac OS X, and some BSDs. Kevent is a much Casey better and more scalable API than select() or poll(). Very cool. Casey I'd like to also write an epoll-based Selector for GNU/Linux, but can't Casey do that right now since my Linux PC went belly-up recently. It looks quite easy given the kqueue code. Yup. Epoll may be even easier, in fact, since it doesn't require holding on to any structures. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.3 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEVAwUBRNfiz+RILCRAfKHCAQLBWwf6Ay1sq8NL0erdM0HwFIOytAD9jU4XRHic jx2dxbLaDq5qIEFc94t7xpC0VCS17iDkquVHTv09unnQNTjUgjQqZ9mBYCW0RwTJ MssTtYtB7ZP/05wCIF+c8Fzx9FggzzzQK4DyyPkjXZW/50F4BaBk5ipsmJqQ6oom AwEHa37Q0/6vkfKVYoAUVjMYThEXJt+Ec34Je4n7nFU8KIyLYarN5bWjphoTVa/g eT2Q6c1N+ro5ESjC3KbmJxXMFCbjLOiAEksvpGFlluM4U4NFoDQpOucoWLvXCn5w kDm0DqzQ9lwwsStQWPhasx+c+5GMj0HsaHQIH/0I1hWpZ2GpwPNhmA== =xqCJ -END PGP SIGNATURE-
[cp-patches] FYI: fix some direct ByteBuffer bugs.
Our implementation of direct byte buffers has some bugs, two of which are fixed by this patch. I'll check in a Mauve test for these soon. NIO in general is in dire need of some serious attention; I have a feeling that these two nits are just the tip of the iceberg. 2006-08-06 C. Scott Marshall [EMAIL PROTECTED] Fixes PR 28608. * java/nio/DirectByteBufferImpl.java (duplicate): only reset if the mark has been set. * native/jni/java-nio/java_nio_VMDirectByteBuffer.c (Java_java_nio_VMDirectByteBuffer_allocate): zero out the allocated data. Thanks. Index: java/nio/DirectByteBufferImpl.java === RCS file: /cvsroot/classpath/classpath/java/nio/DirectByteBufferImpl.java,v retrieving revision 1.21 diff -u -B -b -r1.21 DirectByteBufferImpl.java --- java/nio/DirectByteBufferImpl.java 3 Aug 2005 13:12:59 - 1.21 +++ java/nio/DirectByteBufferImpl.java 6 Aug 2006 20:45:48 - @@ -232,6 +232,7 @@ private ByteBuffer duplicate(boolean readOnly) { int pos = position(); +if (this.mark != -1) reset(); int mark = position(); position(pos); Index: native/jni/java-nio/java_nio_VMDirectByteBuffer.c === RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c,v retrieving revision 1.14 diff -u -B -b -r1.14 java_nio_VMDirectByteBuffer.c --- native/jni/java-nio/java_nio_VMDirectByteBuffer.c 25 Jan 2006 10:40:12 - 1.14 +++ native/jni/java-nio/java_nio_VMDirectByteBuffer.c 6 Aug 2006 20:45:48 - @@ -60,6 +60,8 @@ return 0; } + memset (buffer, 0, capacity); + return JCL_NewRawDataObject (env, buffer); } signature.asc Description: OpenPGP digital signature
Re: [cp-patches] Patch: RFC: add javah tool
On Jul 27, 2006, at 3:10 PM, Tom Tromey wrote: This tool uses the ASM library. I added a new configure option for this, point --with-asm to the all jar and javah will be built. Otherwise it won't be. I disabled javah in the Eclipse-based build (something we should discuss -- maybe we should assume the user will download Escher and ASM?). Maybe we should include our own version of ASM (with the package name changed)? Since javah is a crucial program, avoiding an external dependency for it, and ensuring that it is always built, is much more friendly. PGP.sig Description: This is a digitally signed message part
[cp-patches] [ssl-nio] bug fixes
This fixes some bugs in Jessie found through testing the implementation against itself (Mauve tests, which I'll add there at some point). I'm planning to merge the Jessie code back to the generics branch sometime after the next release is made. It seems complete and stable enough that it is sufficient to replace the existing implementation. SRP is still not yet reimplemented, but this isn't that big a deal, since I don't think it is widely used, and the spec is still only a draft at this point. Thanks. 2006-07-18 Casey Marshall [EMAIL PROTECTED] * gnu/javax/net/ssl/provider/ClientHandshake.java (implHandleInput, implHandleOutput): fix PSK exchange handling. (ClientDHGen.full): new field. (ClientDHGen.implRun): run full key exchange if `full' is true. (ClientDHGen.serverKey): new method. (RSAGen.full): new field. (RSAGen.implRun): run full key exchange if `full' is true. * gnu/javax/net/ssl/provider/ClientDHE_PSKParameters.java (params): slice the buffer. * gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java (init): use `dhParams,' not `buffer.' (params): slice the buffer. * gnu/javax/net/ssl/provider/ServerKeyExchange.java (length): handle case where parameters or signature are null. * gnu/javax/net/ssl/provider/ClientRSA_PSKParameters.java (version): removed. (init): don't take version argument. (init): don't take version argument; take buffer argument. (secret): pass TLS_1 to EncryptedPreMasterSecret constructor. * gnu/javax/net/ssl/provider/CipherSuite.java (isResolved): new field. (init, init): set `isResolved.' (resolve): add PSK cipher suite detection. (isResolved): new method. * gnu/javax/net/ssl/provider/ServerHandshake.java (serverKey): new field. (chooseSuites): choose NONE key exchanges, too; omit unresolved cipher suites. (implHandleInput, implHandleOutput): fix PSK handling. (checkKeyExchange): update for NONE and PSK exchanges. (CertLoader.implRun): grab our private key here. (RSAKeyExchange.implRun): initialize RSA cipher with our private key. (RSA_PSKExchange.implRun): likewise. * gnu/javax/net/ssl/provider/ExchangeKeys.java (init): duplicate and order the buffer; handle null argument. * gnu/javax/net/ssl/provider/ClientKeyExchange.java (exchangeKeys): handle NONE exchange. * gnu/javax/net/ssl/provider/SSLContextImpl.java (engineInit): handle PSK key managers properly. * gnu/javax/net/ssl/provider/SSLEngineImpl.java (init): remove debug logging. * gnu/javax/net/ssl/provider/ServerDHParams.java (init): duplicate and order the buffer. * gnu/javax/crypto/RSACipherImpl.java (doFinal): allow short input. (rsaDecrypt): ensure there's a leading zero. * gnu/javax/net/ssl/provider/EmptyExchangeKeys.java: new file. ### Eclipse Workspace Patch 1.0 #P classpath-ssl-nio Index: gnu/javax/net/ssl/provider/ClientHandshake.java === RCS file: /cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/Attic/ClientHandshake.java,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 ClientHandshake.java --- gnu/javax/net/ssl/provider/ClientHandshake.java 15 Jul 2006 00:51:02 - 1.1.2.2 +++ gnu/javax/net/ssl/provider/ClientHandshake.java 18 Jul 2006 07:59:42 - @@ -56,6 +56,7 @@ import java.security.AccessController; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; +import java.security.KeyManagementException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; @@ -69,11 +70,14 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.Inflater; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; @@ -223,6 +227,7 @@ } } + KeyExchangeAlgorithm kex = engine.session().suite.keyExchangeAlgorithm(); if (continuedSession) { byte[][] keys = generateKeys(clientRandom, serverRandom, @@ -230,8 +235,13 @@ setupSecurityParameters(keys, true, engine, compression); state = READ_FINISHED; } - else + else if (kex == RSA || kex == DH_DSS || kex == DH_RSA + || kex == DHE_DSS || kex == DHE_RSA || kex == RSA_PSK) state
Re: [cp-patches] RFC: Clone fix for gnu.java.security.OID
On Jul 13, 2006, at 3:15 PM, Mark Wielaard wrote: Hi, On Wed, 2006-07-12 at 19:24 +0200, Mario Torre wrote: This patch is hopefully a fix for clone method in gnu.java.security.OID.java Can someone please comment on this? Maybe Casey knows more since he seems to have written the original. I'll just note that your implementation does copy the relative boolean field which the old code didn't do (I suspect that was a bug in the old code). Yeah, using `Object.clone()' is the preferred approach. Using it in OID is correct. PGP.sig Description: This is a digitally signed message part
Re: [cp-patches] RFA: Crypto CipherAdapter.init parameter check
On Jul 10, 2006, at 6:38 PM, Matthew Wringe wrote: This patch is in relation to bug 28104: Cipher.init(...) does not check if the passed parameters are valid: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28104 The patch adds a simple test to the CipherAdapter that will throw a InvalidAlgorithmParameterException if the IV size does not match the block size of the cipher. Thanks, Looks good. Please commit. Thanks. PGP.sig Description: This is a digitally signed message part
[cp-patches] [ssl-nio] client handshake; socket API
This patch implements client-side handshaking (which enables use of SSL clients) and the SSLSocket and SSLServerSocket APIs (the blocking- IO API from previous versions of Java). This patch also puts long- running tasks in the server handshake into delegated tasks, which are run in separate threads, so as not to block the main IO thread. This essentially implements almost everything needed for the JSSE API; the remaining tasks now are to fix bugs (which are numerous) and possibly to implement some more crypto algorithms, such as PSK, OpenPGP certificates, and SRP. I've gotten Classpath's HTTPS handler to work (meaning that client-side SSLSockets work) but haven't tested server sockets. Thanks. 2006-07-12 Casey Marshall [EMAIL PROTECTED] * gnu/javax/net/ssl/provider/AbstractHandshake.java (engine, inParams, outParams, tasks, serverRandom, clientRandom, compression): new fields. (init): take an SSLEngineImpl parameter; init `tasks.' (handleInput): return NEED_TASK if we have tasks. (getInputParams, getOutputParams): implement here; mark final. (getTask): new method. (checkKeyExchange): new method. (reallocateBuffer): use `compact.' (diffieHellmanPhase1, diffieHellmanPhase2): removed. (DHPhase, CertVerifier): new classes. (generateMasterSecret): add asserts. (setupSecurityParameters): new method. * gnu/javax/net/ssl/provider/Certificate.java (certificates): fix reading multiple certificates. * gnu/javax/net/ssl/provider/ClientCertificateTypeList.java: implement IterableClientCertificateType. (iterator): new method. * gnu/javax/net/ssl/provider/ClientDiffieHellmanPublic.java: make public; implement Builder. (init): make public. (init): new constructor. (wrap): new method. (buffer): new method. (publicValue): make public; use `rewind.' (setPublicValue): use `Util.trim;' use `rewind.' (length): return proper length. * gnu/javax/net/ssl/provider/ClientHandshake.java: new file. * gnu/javax/net/ssl/provider/ClientKeyExchange.java: remove unused imports; make public, non-final. (buffer): make protected, non-final. (suite, version): make protected. (init): make public. (length): return 0 for NONE key exchange algorithm. * gnu/javax/net/ssl/provider/ClientKeyExchangeBuilder.java: new file. * gnu/javax/net/ssl/provider/DelegatedTask.java: new file. * gnu/javax/net/ssl/provider/DiffieHellman.java (getParams): use AccessController instead of Util. * gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java: make public; implement Builder. (init): make public. (init): new constructor. (buffer): new method. (encryptedSecret): make public; fix SSLv3 handling. (setEncryptedSecret): make public; rewind the buffer after putting the value. (length): fix length computation. * gnu/javax/net/ssl/provider/ExchangeKeys.java: make public. (buffer): make protected, non-final. (init): made public; don't check null. * gnu/javax/net/ssl/provider/Jessie.java (init): add SSL alias. * gnu/javax/net/ssl/provider/ServerHandshake.java: clean up unused imports. (engine, compression, clientRandom, serverRandom, clientSessionID, inParams, outParams, keyAgreement): moved to superclass. (genDH, certVerifier, certLoader, keyExchangeTask): new fields. (init): pass engine to superclass constructor. (implHandleInput): throw `AlertException' when it makes sense; run long-running tasks as delegated tasks; return NEED_TASK if we scheduled a delegated task. (implHandleOutput): generate keys for continued sessions; run long-running tasks as delegated tasks; return NEED_TASK if we scheduled a delegated task. (status): also return NEED_TASK as appropriate. (getInputParams, getOutputParams): removed. (checkKeyExchange): new method. (genDiffieHellman): removed. (signParams): throw exceptions. (CertLoader, GenDH, RSAKeyExchange): new classes. * gnu/javax/net/ssl/provider/SSLContextImpl.java (engineGetServerSocketFactory): implement. (engineGetSocketFactory): implement. (defaultRandom): use AccessController instead of Util. * gnu/javax/net/ssl/provider/SSLEngineImpl.java (init): use `defaultSuites.' (defaultSuites): new method. (startHandshake): start client handshake in client mode. (getDelegatedTask): implement. (unwrap, wrap): send alert if we catch an AlertException during handshaking. * gnu/javax/net/ssl/provider/SSLServerSocketFactoryImpl.java: new file. * gnu/javax/net/ssl
Re: [cp-patches] RFC: (PR27649) Dependency on gnu.classpath.SystemProperties in crypto code
On Jul 10, 2006, at 7:12 PM, Vivek Lakshmanan wrote: Hi, This is an update to http://developer.classpath.org/pipermail/ classpath-patches/2006-June/002635.html. Replaces SystemProperties.getProperty with GetPropertyAction in an AccessController.doPrivileged block. Since this idea has been approved already, I will commit this tomorrow unless there are any objections in the mean time. Looks fine, just lines like these -String ls = SystemProperties.getProperty(line.separator); +String ls = (String) AccessController.doPrivileged(new GetPropertyAction( + line.separator)); should be on one line (Eclipse did this, I bet). When there are are long lines without good places to break, I tend to break before an opening parenthesis, or before a period. Something like this: String ls = (String) AccessController.doPrivileged (new GetPropertyAction(line.separator)); Although, I don't know what others prefer for situations like this. PGP.sig Description: This is a digitally signed message part
[cp-patches] [ssl-nio] Fixes for server-side handshakes
I'm checking this in. This patch irons out a lot of the little bugs in the server-side SSL handshake, so now, at least for Diffie-Hellman based cipher suites, Jessie can now serve up simple HTTPS requests. This basically marks a nice halfway point in this project: still left to do is the client- side handshake and reimplementing the blocking-IO SSLSocket, as well as fixing the remaining bugs. 2006-07-09 Casey Marshall [EMAIL PROTECTED] * gnu/javax/net/ssl/AbstractSessionContext.java (newInstance): return `AbstractSessionContext.' (getSession): check if the session is null. * gnu/javax/net/ssl/Session.java (packetBufferSize): removed. (init): initialize `applicationBufferSize.' (getPacketBufferSize): return application buffer size, plus 2048. * gnu/javax/net/ssl/provider/AbstractHandshake.java (PAD1, PAD2): new constants. (handleInput): implement; call `implHandleOutput,' and hash messages as they are consumed. (implHandleInput): new abstract method. (handleOutput): fix hashing of produced bytes. (status, handleV2Hello): new abstract methods. (pollHandshake): don't hash the input here; add logging. (hasMessage): add logging. (reallocateBuffer): shift the existing contents down in the buffer, if it is, on the whole, large enough for new input. (genV2CertificateVerify): renamed... (genV3CertificateVerify): to this, which is correct. (generateKeys): fix PRF setup; generate an IV for 1.1; add logging. (generateFinished): add logging; update with correct padding. (generateMasterSecret): add logging; fix PRF initialization. * gnu/javax/net/ssl/provider/CipherSuite.java (mac): use mac algorithm name HMac-SHA1. * gnu/javax/net/ssl/provider/ClientHello.java: make extendable. * gnu/javax/net/ssl/provider/ClientHelloBuilder.java: new file. * gnu/javax/net/ssl/provider/ClientHelloV2.java (init): order the input buffer BIG_ENDIAN. (cipherSpecs): made public; use qualified return type. * gnu/javax/net/ssl/provider/Debug.java: new file. * gnu/javax/net/ssl/provider/Extension.java (init): order the input buffer BIG_ENDIAN. (length): return the total length, including the length field. (toString): add prefix to value. * gnu/javax/net/ssl/provider/ExtensionList.java (init): order the input buffer BIG_ENDIAN. * gnu/javax/net/ssl/provider/InputSecurityParameters.java (logger): new constant. (suite): new field. (init): also take a `CipherSuite' argument. (decrypt): use `update,' not `doFinal' for decryption; add debug logging; fix mac computation; fix copying fragment to output. (cipherSuite): return `suite' field. * gnu/javax/net/ssl/provider/Jessie.java (init): add TLSv1.1-RSA signature. * gnu/javax/net/ssl/provider/OutputSecurityParameters.java (logger): new constant. (suite): new field. (init): take additional `CipherSuite' argument. (encrypt): add debug logging; fix mac computation; various little fixes. (suite): new method. * gnu/javax/net/ssl/provider/ProtocolVersion.java (forName): also recognize TLSv1.1. * gnu/javax/net/ssl/provider/Random.java (copy): fix copying the internal buffer. * gnu/javax/net/ssl/provider/Record.java (init): order the input buffer BIG_ENDIAN. (toString): include length in output. * gnu/javax/net/ssl/provider/SSLContextImpl.java (serverContext, clientContext): declare both as `AbstractSessionContext.' * gnu/javax/net/ssl/provider/SSLEngineImpl.java (logger): make an instance of `SystemLogger.' (mode): declare as a Mode. (Mode): new enum. (init): add logging; initialize `enabledProtocols' and `enabledSuites.' (beginHandshake): debug logging; handle Mode enum. (closeOutbound): prepare `lastAlert' to carry the close alert. (isInboundDone, isOutboundDone): implement. (setUseClientMode): use Mode enum. (unwrap): fix V2 hello handling; optimize calls when the cipher suite is TLS_NULL_WITH_NULL_NULL; add debug logging; handle closue alerts properly; fix record length reporting. (wrap): set `outClosed' if we are sending a closure alert here; delay changing output security params until we emit the change notification; optimize initial handshake; fix input buffer consumption; handle end of handshake. * gnu/javax/net/ssl/provider/SSLRSASignatureImpl.java: new file. * gnu/javax/net/ssl/provider/ServerDHParams.java (buffer): set position to 0 in the buffer we return. * gnu/javax/net/ssl/provider/ServerHandshake.java (version, suite
Re: [cp-patches] RFC: Crypto PBEKeySpec password references
On Jul 5, 2006, at 12:20 PM, Matthew Wringe wrote: After looking into this issue more, PBEKeySpec needs to also create a copy of the salt, and some of the PBEKeySpec implementation is not according to spec. Please find attached a patch for PBEKeySpec(Crypto-PBEKeySpec.patch). This patch now only stores clones of the password and salt arguments, as well as checking arguments being passed for validity. The javadoc has also been updated to reflect that only copies of the passed parameters are being stored. I am also attaching a mauve testlet for this class (TestOfPBEKeySpec.java). This test should go into gnu/testlet/javax/crypto/spec (and as this directory does not exist yet in cvs, I could not just create a nice patch) Please review and comment. I do not have classpath commit permissions nor mauve commit permissions, so if this is deemed acceptable, could someone please submit them for me. This looks fine; I think most of us agree that it's OK if we give you commit access, so you can go ahead and check this in yourself when that's done. Thanks! PGP.sig Description: This is a digitally signed message part
Re: [cp-patches] X/Escher peers
On Jun 28, 2006, at 8:35 AM, Roman Kennke wrote: The X/Escher peers for inclusion in Classpath. After some email exchange with Mark I think it would be best to handle the dependency on Escher just as we handle other dependecies on external libs (GTK, Qt). The only problem beeing this lib is Java, and I have no clue how to teach that to the autotools. Maybe someone has an idea? There's this: http://ac-archive.sourceforge.net/Java_Support/ ac_check_class.html A few GNU Java projects I've run into use these macros (my projects included). I don't think they're ideal, but should suffice. The main page is http://ac-archive.sourceforge.net/Java_Support/ PGP.sig Description: This is a digitally signed message part
Re: [cp-patches] X/Escher peers
On Jun 28, 2006, at 8:35 AM, Roman Kennke wrote: The X/Escher peers for inclusion in Classpath. After some email exchange with Mark I think it would be best to handle the dependency on Escher just as we handle other dependecies on external libs (GTK, Qt). The only problem beeing this lib is Java, and I have no clue how to teach that to the autotools. Maybe someone has an idea? A --with-escher-jar=/path/to/escher.jar option would be a start. Also, we need to exclude the X peer classes from build when no such jar is found. Trying out the peers: Escher needs to be in the bootclasspath. The current JAR can be found here (older versions won't work): http://kennke.org/~roman/escher-0.2.3-pre.jar Oh, and also, why can't we include the Escher source in external/? It sounds to me like it needs to be forked anyway (especially if it's going to get Xauthority handling, which it definitely needs). Is the author even working on it any more? PGP.sig Description: This is a digitally signed message part
[cp-patches] [ssl-nio] 1.5 Signature methods.
This adds methods to Signature and SignatureSpi that take a ByteBuffer as input. 2006-06-28 Casey Marshall [EMAIL PROTECTED] * java/security/Signature.java (update): new method. * java/security/SignatureSpi.java (engineUpdate): new method. Committed. ### Eclipse Workspace Patch 1.0 #P classpath-ssl-nio Index: java/security/Signature.java === RCS file: /cvsroot/classpath/classpath/java/security/Signature.java,v retrieving revision 1.15.2.4 diff -u -r1.15.2.4 Signature.java --- java/security/Signature.java2 Mar 2006 09:33:59 - 1.15.2.4 +++ java/security/Signature.java28 Jun 2006 22:54:16 - @@ -40,6 +40,7 @@ import gnu.java.security.Engine; +import java.nio.ByteBuffer; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.spec.AlgorithmParameterSpec; @@ -467,6 +468,22 @@ else throw new SignatureException(); } + + /** + * Update this signature with the [EMAIL PROTECTED] java.nio.Buffer#remaining()} + * bytes of the input buffer. + * + * @param input The input buffer. + * @throws SignatureException If this instance was not properly + * initialized. + */ + public final void update(ByteBuffer input) throws SignatureException + { +if (state != UNINITIALIZED) + engineUpdate(input); +else + throw new SignatureException(not initialized); + } /** * Returns the name of the algorithm currently used. The names of algorithms Index: java/security/SignatureSpi.java === RCS file: /cvsroot/classpath/classpath/java/security/SignatureSpi.java,v retrieving revision 1.7.2.5 diff -u -r1.7.2.5 SignatureSpi.java --- java/security/SignatureSpi.java 2 Mar 2006 09:33:59 - 1.7.2.5 +++ java/security/SignatureSpi.java 28 Jun 2006 22:54:16 - @@ -37,6 +37,7 @@ package java.security; +import java.nio.ByteBuffer; import java.security.spec.AlgorithmParameterSpec; /** @@ -131,6 +132,24 @@ throws SignatureException; /** + * Update this signature with the [EMAIL PROTECTED] java.nio.Buffer#remaining()} + * bytes of the given buffer. + * + * @param input The input buffer. + * @throws SignatureException + */ + protected void engineUpdate(ByteBuffer input) throws SignatureException + { +byte[] buf = new byte[4096]; +while (input.hasRemaining()) + { +int l = Math.min(input.remaining(), buf.length); +input.get(buf, 0, l); +engineUpdate(buf, 0, l); + } + } + + /** * Returns the signature bytes of all the data fed to this instance. The * format of the output depends on the underlying signature algorithm. * PGP.sig Description: This is a digitally signed message part
[cp-patches] [ssl-nio] gnu.java.security cosmetics
This makes GetSecurityPropertyAction implement PrivilegedActionString, and adds the @Requires annotation that I've mentioned previously. 2006-06-28 Casey Marshall [EMAIL PROTECTED] * gnu/java/security/Requires.java: new annotation. * gnu/java/security/action/GetSecurityPropertyAction.java: implement PrivilegedActionString. (run): return String. Committed. ### Eclipse Workspace Patch 1.0 #P classpath-ssl-nio Index: gnu/java/security/action/GetSecurityPropertyAction.java === RCS file: /cvsroot/classpath/classpath/gnu/java/security/action/GetSecurityPropertyAction.java,v retrieving revision 1.2.2.3 diff -u -r1.2.2.3 GetSecurityPropertyAction.java --- gnu/java/security/action/GetSecurityPropertyAction.java 2 Aug 2005 20:12:12 - 1.2.2.3 +++ gnu/java/security/action/GetSecurityPropertyAction.java 28 Jun 2006 23:10:07 - @@ -50,7 +50,7 @@ * String passwd = AccessController.doPrivileged(action); * /code */ -public class GetSecurityPropertyAction implements PrivilegedAction +public class GetSecurityPropertyAction implements PrivilegedActionString { private String name; private String value; @@ -83,7 +83,7 @@ return this; } - public Object run() + public String run() { String val = Security.getProperty(name); if (val == null) Index: gnu/java/security/Requires.java === RCS file: gnu/java/security/Requires.java diff -N gnu/java/security/Requires.java --- /dev/null 1 Jan 1970 00:00:00 - +++ gnu/java/security/Requires.java 1 Jan 1970 00:00:00 - @@ -0,0 +1,59 @@ +/* Requires.java -- mark methods as requiring permission. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +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 gnu.java.security; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; +import java.security.Permission; + +/** + * + * + * @author Casey Marshall ([EMAIL PROTECTED]) + */ [EMAIL PROTECTED] @Retention(CLASS) @Target(METHOD) +public @interface Requires +{ + Class? extends Permission permissionClass(); + String target(); + String action(); +} PGP.sig Description: This is a digitally signed message part
[cp-patches] [ssl-nio] gnu.javax.net.ssl updates
This turns SessionStore into AbstractSessionContext, a skeletal implementation of the SessionContext interface, fleshes out some more of the Session class (itself a skeletal implementation of the SSLSession interface), and uses generic collection types in PrivateCredentials. 2006-06-28 Casey Marshall [EMAIL PROTECTED] * gnu/javax/net/ssl/AbstractSessionContext.java: renamed from `SessionStore.' Implement SessionContext. * gnu/javax/net/ssl/PrivateCredentials.java: genericize collections. * gnu/javax/net/ssl/Session.java (packetBufferSize): new field. (values): genericize. (random): make transient. (truncatedMac, context): new fields. (getLocalPrincipal, getPacketBufferSize, getPeerPrincipal) (getSessionContext): implement. (isTruncatedMac): new method. (repair, privateData, setPrivateData): new abstract methods. (PrivateData.serialVersionUID): new constant. * gnu/javax/net/ssl/SessionStore.java: renamed to `AbstractSessionContext.' Committed. ### Eclipse Workspace Patch 1.0 #P classpath-ssl-nio Index: gnu/javax/net/ssl/Session.java === RCS file: /cvsroot/classpath/classpath/gnu/javax/net/ssl/Attic/Session.java,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 Session.java --- gnu/javax/net/ssl/Session.java 3 Jun 2006 07:46:44 - 1.1.2.1 +++ gnu/javax/net/ssl/Session.java 28 Jun 2006 23:15:40 - @@ -46,15 +46,20 @@ import java.util.Arrays; import java.util.HashMap; -import java.util.Iterator; +import java.util.Set; +import javax.crypto.SealedObject; +import javax.net.ssl.SSLException; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSessionBindingEvent; +import javax.net.ssl.SSLSessionBindingListener; +import javax.net.ssl.SSLSessionContext; import javax.security.cert.X509Certificate; /** * A concrete implementation of the [EMAIL PROTECTED] SSLSession} interface. This - * class is provided to allow pluggable [EMAIL PROTECTED] SessionStore} + * class is provided to allow pluggable [EMAIL PROTECTED] AbstractSessionContext} * implementations. */ public abstract class Session implements SSLSession, Serializable @@ -62,6 +67,9 @@ protected final long creationTime; protected long lastAccessedTime; protected int applicationBufferSize; + + // Default to 2^14 + 5 -- the maximum size for a record. + protected int packetBufferSize = 16389; protected ID sessionId; protected Certificate[] localCerts; protected Certificate[] peerCerts; @@ -69,127 +77,207 @@ protected String peerHost; protected int peerPort; protected boolean peerVerified; - protected HashMap values; + protected HashMapString,Object values; protected boolean valid; - protected SecureRandom random; + protected boolean truncatedMac = false; + transient protected SecureRandom random; + transient protected SSLSessionContext context; - protected Session () + protected Session() { -creationTime = System.currentTimeMillis (); -values = new HashMap (); +creationTime = System.currentTimeMillis(); +values = new HashMapString, Object(); } - public void access () + public void access() { lastAccessedTime = System.currentTimeMillis (); } - public int getApplicationBufferSize () + public int getApplicationBufferSize() { return applicationBufferSize; } - public String getCipherSuite () + public String getCipherSuite() { return null; } - public long getCreationTime () + public long getCreationTime() { return creationTime; } - public byte[] getId () + public byte[] getId() { -return sessionId.id (); +return sessionId.id(); } - public ID id () + public ID id() { return sessionId; } - public long getLastAccessedTime () + public long getLastAccessedTime() { return lastAccessedTime; } - public Certificate[] getLocalCertificates () + public Certificate[] getLocalCertificates() { if (localCerts == null) return null; -return (Certificate[]) localCerts.clone (); +return (Certificate[]) localCerts.clone(); } - public Certificate[] getPeerCertificates () throws SSLPeerUnverifiedException + public Principal getLocalPrincipal() + { +if (localCerts != null) + { +if (localCerts[0] instanceof java.security.cert.X509Certificate) + return ((java.security.cert.X509Certificate) localCerts[0]).getSubjectDN(); + } +return null; + } + + public int getPacketBufferSize() + { +return packetBufferSize; + } + + public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { if (!peerVerified) - throw new SSLPeerUnverifiedException (peer not verified); + throw new SSLPeerUnverifiedException(peer not verified
[cp-patches] [ssl-nio] update tests
This updates some tests for the new Builder interfaces. 2006-06-28 Casey Marshall [EMAIL PROTECTED] * jessie-tests/testCertificate.java: update for Builder interface and API changes. * jessie-tests/testServerHello.java: likewise. * jessie-tests/testServerKeyExchange.java: likewise. Committed. ### Eclipse Workspace Patch 1.0 #P classpath-ssl-nio Index: jessie-tests/testServerHello.java === RCS file: /cvsroot/classpath/classpath/jessie-tests/Attic/testServerHello.java,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 testServerHello.java --- jessie-tests/testServerHello.java 11 Jun 2006 07:23:24 - 1.1.2.2 +++ jessie-tests/testServerHello.java 29 Jun 2006 00:35:28 - @@ -7,6 +7,7 @@ import gnu.javax.net.ssl.provider.ProtocolVersion; import gnu.javax.net.ssl.provider.Random; import gnu.javax.net.ssl.provider.ServerHello; +import gnu.javax.net.ssl.provider.ServerHelloBuilder; import java.nio.ByteBuffer; import java.util.Arrays; @@ -35,7 +36,7 @@ handshake.setType (Handshake.Type.SERVER_HELLO); handshake.setLength (alloc_len - 4); -ServerHello hello = (ServerHello) handshake.body (); +ServerHelloBuilder hello = new ServerHelloBuilder(); hello.setVersion (ProtocolVersion.TLS_1); Random random = hello.random (); @@ -60,26 +61,27 @@ exts.get(1).setValue(new byte[3]); handshake.setLength (hello.length ()); +handshake.bodyBuffer().put(hello.buffer()); System.err.println (handshake); handshake = new Handshake (buffer); -hello = (ServerHello) handshake.body (); -if (Arrays.equals (sessionId, hello.sessionId ())) +ServerHello hello2 = (ServerHello) handshake.body (); +if (Arrays.equals (sessionId, hello2.sessionId ())) System.out.println (PASS: sessionId); else System.out.println (FAIL: sessionId); -if (hello.cipherSuite () == CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA) +if (hello2.cipherSuite () == CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA) System.out.println (PASS: cipherSuite); else System.out.println (FAIL: cipherSuite); -if (hello.compressionMethod () == CompressionMethod.ZLIB) +if (hello2.compressionMethod () == CompressionMethod.ZLIB) System.out.println (PASS: compressionMethod); else System.out.println (FAIL: compressionMethod); -exts = hello.extensions(); +exts = hello2.extensions(); Extension e = exts.get(0); if (e.type() == Extension.Type.MAX_FRAGMENT_LENGTH) System.out.println (PASS: extensions().get(0).type); @@ -107,7 +109,7 @@ handshake.setType (Handshake.Type.SERVER_HELLO); handshake.setLength (70); -hello = (ServerHello) handshake.body (); +hello = new ServerHelloBuilder(); hello.setVersion (ProtocolVersion.TLS_1); // 2 random = hello.random (); @@ -122,9 +124,11 @@ hello.setSessionId (sessionId); // + 33 hello.setCipherSuite (CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA); // + 2 hello.setCompressionMethod (CompressionMethod.ZLIB); // + 1 +handshake.setLength(hello.length()); +handshake.bodyBuffer().put(hello.buffer()); handshake = new Handshake (buffer); -hello = (ServerHello) handshake.body(); +hello2 = (ServerHello) handshake.body(); if (hello.extensions() == null) System.out.println (PASS: hello.extensions() == null); else Index: jessie-tests/testServerKeyExchange.java === RCS file: /cvsroot/classpath/classpath/jessie-tests/Attic/testServerKeyExchange.java,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 testServerKeyExchange.java --- jessie-tests/testServerKeyExchange.java 3 Jun 2006 07:44:41 - 1.1.2.1 +++ jessie-tests/testServerKeyExchange.java 29 Jun 2006 00:35:28 - @@ -1,5 +1,6 @@ import gnu.javax.net.ssl.provider.CipherSuite; import gnu.javax.net.ssl.provider.Handshake; +import gnu.javax.net.ssl.provider.ProtocolVersion; import gnu.javax.net.ssl.provider.ServerKeyExchange; import gnu.javax.net.ssl.provider.ServerRSAParams; import gnu.javax.net.ssl.provider.Signature; @@ -26,7 +27,7 @@ static void check () throws Exception { ByteBuffer buffer = ByteBuffer.allocate (1024); -Handshake handshake = new Handshake (buffer, CipherSuite.SSL_RSA_WITH_NULL_MD5); +Handshake handshake = new Handshake (buffer, CipherSuite.TLS_RSA_WITH_NULL_MD5, ProtocolVersion.TLS_1_1); handshake.setType (Handshake.Type.SERVER_KEY_EXCHANGE); handshake.setLength (1019); @@ -46,7 +47,7 @@ handshake.setLength (kex.length ()); -handshake = new Handshake (buffer, CipherSuite.SSL_RSA_WITH_NULL_MD5); +handshake = new Handshake (buffer, CipherSuite.TLS_RSA_WITH_NULL_MD5, ProtocolVersion.TLS_1_1); kex = (ServerKeyExchange) handshake.body (); params = (ServerRSAParams) kex.params
[cp-patches] [ssl-nio] Extension value types
This implements the SSL hello extension values from RFC 3546. These extensions allow clients to request extended functionality from a server. It's unlikely that we will support all of these extensions in Jessie, at least not in this Summer of Code release, but we can still recognize and parse them. Lots of these new classes turned out to be pseudo-list types, and also implement Iterable for their underlying list type. There are a lot of these kinds of lists; unifying them may be a good idea, eventually. 2006-06-10 Casey Marshall [EMAIL PROTECTED] * gnu/javax/net/ssl/provider/ServerHello.java (extensions): return an ExtensionList. (setExtensionsLength): set the length in the buffer. (toString): print out individual extensions. * gnu/javax/net/ssl/provider/Extension.java (valueBytes): new method. (valueBuffer): new method. (value): return an Extenion.Value. (toString): print out extension value. (Value): new abstract inner class. * gnu/javax/net/ssl/provider/ClientHello.java (extensions): return an ExtensionList. (setExtensionListLength): set the length in the buffer. (toString): print out extensions. * gnu/javax/net/ssl/provider/ServerHandshake.java (chooseSuite, chooseCompression): use generics and foreach loops. * gnu/javax/net/ssl/provider/ExtensionList.java: new class. * gnu/javax/net/ssl/provider/MaxFragmentLength.java: new class. * gnu/javax/net/ssl/provider/CertificateURL.java: new class. * gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java: new class. * gnu/javax/net/ssl/provider/TruncatedHMAC.java: new class. * gnu/javax/net/ssl/provider/ServerNameList.java: new class. * gnu/javax/net/ssl/provider/TrustedAuthorities.java: new class. * gnu/javax/net/ssl/provider/CertificateStatusType.java: new class. * gnu/javax/net/ssl/provider/CertificateStatusRequest.java: new class. Committed. ### Eclipse Workspace Patch 1.0 #P classpath-ssl-nio Index: gnu/javax/net/ssl/provider/ServerHello.java === RCS file: /cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/ServerHello.java,v retrieving revision 1.1.4.1.2.1 diff -u -r1.1.4.1.2.1 ServerHello.java --- gnu/javax/net/ssl/provider/ServerHello.java 3 Jun 2006 07:49:53 - 1.1.4.1.2.1 +++ gnu/javax/net/ssl/provider/ServerHello.java 11 Jun 2006 06:50:20 - @@ -67,6 +67,7 @@ SessionID session_id; CipherSuite cipher_suite; CompressionMethod compression_method; + Extensions server_hello_extension_listlt;0..2^16-1gt; } ServerHello; /pre * @@ -171,11 +172,19 @@ return CompressionMethod.getInstance (buffer.get (offset) 0xFF); } - public ByteBuffer extensions () + public ExtensionList extensions () { int offset = SESSID_OFFSET + (buffer.get (SESSID_OFFSET) 0xFF) + 4; -return ((ByteBuffer) buffer.duplicate ().position (offset) -.limit (totalLength)).slice (); +if (offset == totalLength) + return null; +if (buffer.limit() = offset) + return null; +int len = buffer.getShort(offset) 0x; +if (len == 0) + len = buffer.limit() - offset - 2; +ByteBuffer ebuf = ((ByteBuffer) buffer.duplicate ().position (offset) + .limit (offset + len + 2)).slice (); +return new ExtensionList (ebuf); } public void setVersion (final ProtocolVersion version) @@ -213,7 +222,9 @@ public void setExtensionsLength (final int length) { totalLength = (SESSID_OFFSET + (buffer.get (SESSID_OFFSET) 0xFF) - + 4 + length); + + 4 + length + 4); +buffer.putShort (SESSID_OFFSET + (buffer.get (SESSID_OFFSET) 0xFF) + 4, + (short) length); } public String toString () @@ -250,13 +261,11 @@ out.print (compressionMethod: ); out.print (compressionMethod ()); out.println (;); -ByteBuffer extbuf = extensions (); -if (extbuf.limit () 0) - { -out.print (subprefix); -out.println (extensions:); -out.print (Util.hexDump (extbuf, subprefix)); - } +ExtensionList exts = extensions (); +out.print (subprefix); +out.println (extensions:); +out.println (exts != null ? exts.toString (subprefix+ ) +: subprefix + (nil)); if (prefix != null) out.print (prefix); out.print (} ServerHello;); Index: gnu/javax/net/ssl/provider/Extension.java === RCS file: /cvsroot/classpath/classpath/gnu/javax/net/ssl/provider/Extension.java,v retrieving revision 1.1.4.1.2.2 diff -u -r1.1.4.1.2.2 Extension.java --- gnu/javax/net/ssl/provider/Extension.java 6 Jun 2006 01:01:19 - 1.1.4.1.2.2 +++ gnu/javax/net/ssl/provider
[cp-patches] [ssl-nio] update tests
This updates some test classes for the extensions change. 2006-06-10 Casey Marshall [EMAIL PROTECTED] * jessie-tests/testClientHello.java: update for extensions changes. * jessie-tests/testExtensionList.java: likewise. * jessie-tests/testServerHello.java: likewise. ### Eclipse Workspace Patch 1.0 #P classpath-ssl-nio Index: jessie-tests/testExtensionsList.java === RCS file: /cvsroot/classpath/classpath/jessie-tests/Attic/testExtensionsList.java,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 testExtensionsList.java --- jessie-tests/testExtensionsList.java6 Jun 2006 01:01:20 - 1.1.2.1 +++ jessie-tests/testExtensionsList.java11 Jun 2006 07:07:13 - @@ -44,7 +44,7 @@ System.out.println (PASS: get(0).type()); else System.out.println (FAIL: get(0).type()); -if (Arrays.equals (e.value(), new byte[] { 1 })) +if (Arrays.equals (e.valueBytes(), new byte[] { 1 })) System.out.println (PASS: get(0).value()); else System.out.println (FAIL: get(0).value()); @@ -54,7 +54,7 @@ System.out.println (PASS: get(1).type()); else System.out.println (FAIL: get(1).type()); -if (Arrays.equals(e.value(), new byte[3])) +if (Arrays.equals(e.valueBytes(), new byte[3])) System.out.println (PASS: get(1).value()); else System.out.println (FAIL: get(1).value()); Index: jessie-tests/testServerHello.java === RCS file: /cvsroot/classpath/classpath/jessie-tests/Attic/testServerHello.java,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 testServerHello.java --- jessie-tests/testServerHello.java 3 Jun 2006 07:44:41 - 1.1.2.1 +++ jessie-tests/testServerHello.java 11 Jun 2006 07:07:13 - @@ -1,6 +1,8 @@ import gnu.javax.net.ssl.provider.CipherSuite; import gnu.javax.net.ssl.provider.CompressionMethod; +import gnu.javax.net.ssl.provider.Extension; +import gnu.javax.net.ssl.provider.ExtensionList; import gnu.javax.net.ssl.provider.Handshake; import gnu.javax.net.ssl.provider.ProtocolVersion; import gnu.javax.net.ssl.provider.Random; @@ -48,7 +50,14 @@ hello.setSessionId (sessionId); hello.setCipherSuite (CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA); hello.setCompressionMethod (CompressionMethod.ZLIB); -hello.setExtensionsLength (0); +hello.setExtensionsLength (12); +ExtensionList exts = hello.extensions(); +// Max fragment length of 2^9-1 +exts.set (0, Extension.Type.MAX_FRAGMENT_LENGTH, 1); // 2 + 2 + 1 +exts.get (0).setValue (new byte[] { 1 }); +// Zero-length server name. +exts.set (1, Extension.Type.SERVER_NAME, 3); // 2 + 2 + 3 +exts.get(1).setValue(new byte[3]); handshake.setLength (hello.length ()); System.err.println (handshake); @@ -69,5 +78,58 @@ System.out.println (PASS: compressionMethod); else System.out.println (FAIL: compressionMethod); + +exts = hello.extensions(); +Extension e = exts.get(0); +if (e.type() == Extension.Type.MAX_FRAGMENT_LENGTH) + System.out.println (PASS: extensions().get(0).type); +else + System.out.println (FAIL: extensions().get(0).type); +if (Arrays.equals(e.valueBytes(), new byte[] { 1 })) + System.out.println (PASS: extensions().get(0).value); +else + System.out.println (FAIL: extensions().get(0).value); + +e = exts.get(1); +if (e.type() == Extension.Type.SERVER_NAME) + System.out.println (PASS: extensions().get(1).type); +else + System.out.println (FAIL: extensions().get(1).type); +if (Arrays.equals(e.valueBytes(), new byte[3])) + System.out.println (PASS: extensions().get(1).value); +else + System.out.println (FAIL: extensions().get(1).value); + +// Part 2: with no extensions. +buffer = ByteBuffer.allocate (74); +handshake = new Handshake (buffer); + +handshake.setType (Handshake.Type.SERVER_HELLO); +handshake.setLength (70); + +hello = (ServerHello) handshake.body (); + +hello.setVersion (ProtocolVersion.TLS_1); // 2 +random = hello.random (); +random.setGmtUnixTime (123456); +nonce = new byte[28]; +for (int i = 0; i nonce.length; i++) + nonce[i] = (byte) i; +random.setRandomBytes (nonce);// + 32 +sessionId = new byte[32]; +for (int i = 0; i sessionId.length; i++) + sessionId[i] = (byte) i; +hello.setSessionId (sessionId); // + 33 +hello.setCipherSuite (CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA); // + 2 +hello.setCompressionMethod (CompressionMethod.ZLIB); // + 1 + +handshake = new Handshake (buffer); +hello = (ServerHello) handshake.body(); +if (hello.extensions() == null) + System.out.println (PASS: hello.extensions() == null); +else + System.out.println (FAIL: hello.extensions() != null
Re: [cp-patches] RFC: Move gnu.regexp to gnu.java.util.regex
On Jun 7, 2006, at 8:35 AM, Roman Kennke wrote: Hi there, I'd like to propose to rename the gnu.regexp package to gnu.java.util.regex or something. I have a problem here with JEdit which obviously uses an old version of gnu regexp and no hit some AbstractMethodError with this setup. I think it could avoid problems with other apps too. I tried this with JEdit (such refactoring takes some seconds only in eclipse) and got nice syntax highlighting to work in JEdit: http://kennke.org/~roman/jedit2.png Opinions? +1. Keeping our package naming consistent is good. PGP.sig Description: This is a digitally signed message part
Re: [cp-patches] Re: RFC: add a cacerts file under resource/java/security
One nice way to do this ca-certs stuff is to write a keystore implementation that just reads certificates out of a directory, and with each certificate stored in its own file. This would make it a lot easier for Classpath to use the certificates already installed on the system (like Debian's ca-certificates package). If there is a common way most GNU/Linux distros package certs, we'd do good to take advantage of that. We'd really need to update java.security.KeyStore to the 1.5 API to do that, though, because previous versions of the API only accepted an input stream for loading keystores. On Jun 7, 2006, at 11:14 AM, Mark Wielaard wrote: Hi Raif, I CCed the devjam list on which a couple of different distribution packagers are subscribed. Devjam people, Raif added support for importing trusted ca-certs to GNU Classpath so our tls/ssl implementation for example can just reuse the ca-certs that are already packaged for an distribution (for example those used by Mozilla). Feedback on how to make this as easy as possible for distros appreciated (see below). Please forward to any distro-list when appropriate. On Fri, 2006-06-02 at 06:19 +1000, Raif S. Naffah wrote: On Monday 29 May 2006 21:21, Mark Wielaard wrote: On Mon, 2006-05-29 at 21:00 +1000, Raif S. Naffah wrote: On Monday 29 May 2006 20:02, Mark Wielaard wrote: On Mon, 2006-05-22 at 21:42 +1000, Raif S. Naffah wrote: my question is: does anybody see any problem, legal or otherwise, in including our version of this cacerts file which i named cacerts.gkr into the GNU Classpath distribution? I wonder how well that will work with the various distributions. if by distributions you mean the different VMs that use Classpath then this file is not much different than for example classpath.security, which is our version of java.security. No, I was thinking of the GNU/Linux distros. They seem to have their own collection of trusted ca-certs already. So I was wondering whether we could somehow reuse those easily (for example during installation time). That way a user has only one set of ca-certs to worry about. Since at least for Debian it seems every package using ssl uses the same set. http://packages.debian.org/ca-certificates And then we wouldn't have to worry which certificates to include and where they would come from. i downloaded and installed (own --prefix since i don't use a Debian distro) the latest stable ca-certificates package (from http://packages.debian.org/stable/misc/ca-certificates). Devjam people. Hints on how other distros handle this appreciated. i also added CACertCmd as a new command to the keytool --which does not have a counter-part in the RI version-- to import without prompting the user one x.509 certificate from a designated file. this new command is invoked through: keytool -cacert ... a script, import-cacerts.sh, added to the scripts folder, recursively visits a given directory invoking the keytool -cacert command on each file with the following: * the alias of the certificate is constructed from the file name. * the key store password is hard-wired to 'changeit' --similar to the RI version. * the key store is hard-wired to cacerts.gkr in resource/java/ security. Very nice! Please do check this in. all this allows us to build/update a key store of trusted certificates, which can then be included in our deliverables. the new '-cacert' command, although specific to our version of keytool is useful for sysadmins who may want to use something similar in their environment. comments? This seems perfect to let our users decide which cacerts they want to use themselves. If it all possible I would like to not actually ship any trusted ca-certs ourselves since that would put us in the position to decide which ca-certs are actually trusted and when to deprecate which ones for each release. So I would like to add a configure option (say --with-ca-cert-dir=/path/to/ca/cert/dir) which can be used by the user/packager to automatically run the import-cacerts.sh script during the build. Ideally each distribution would then add some package hooks to rerun import-cacerts.sh for classpath whenever the ca-certificates package is updated. I assume something like this is also used for Mozilla or OpenSSL. Devjam people? Cheers, Mark PGP.sig Description: This is a digitally signed message part