Niklas Gustavsson <[email protected]> wrote:
>
> On Wed, Feb 25, 2009 at 8:54 PM, Niklas Gustavsson <[email protected]>
> wrote:
> java.net.SocketException: No such file or directory
> at org.apache.harmony.luni.platform.OSNetworkSystem.read(OSNetworkSystem.java)
> at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:557)
> at
> org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:87)
The error message is quite misleading. It is really a poll syscall
returning EINTR meaning "system call was interrupted by a signal that
was caught". Looks like this piece of code needs "fixing" to handle
being interrupted (by DRLVM use of SIGUSR2) just as the select code has
been.
(Aside: This code was donated by IBM and the IBM VME doesn't use signals
like this so consequently the code wasn't designed to handle this.)
> Some further details on this problem. First of all, it only seems to happen
> for a client that is connected against certain (NIO?) servers.
This is quite puzzling. I can't see why this makes any difference. Perhaps
it is a timing issue.
> Running against netcat for example does not expose the bug. Also,
> it only happens when the socket timeout is set on the client.
This is an easy one. If there is no timeout then the code doesn't do
a poll but just does a read, and read is a syscall that is restarted
automatically if it is interrupted (on "slow" devices like sockets
anyway). (The SIGUSR2 handler is registered with SA_RESTART so the
restart behaviour described in signal(7) applies.)
> Thus, having MINA, SLF4j and FtpServer on the classpath, and running
> the following test case exposes the bug:
> import java.net.InetSocketAddress; import java.net.Socket; import
> java.nio.channels.Channels;
> import org.apache.ftpserver.FtpServer; import org.apache.ftpserver.FtpServerFa
> ctory; import org.apache.ftpserver.listener.ListenerFactory;
> public class HarmonyFtpClient {
> public static void main(String[] args) throws Exception {
> FtpServerFactory fsf = new FtpServerFactory();
> ListenerFactory listenerFactory = new ListenerFactory();
> listenerFactory.setPort(2121);
> fsf.addListener("default", listenerFactory.createListener());
> FtpServer server = fsf.createServer();
> server.start();
> try {
> Socket socket = new Socket();
> socket.connect(new InetSocketAddress("localhost", 2121));
> socket.setSoTimeout(10000);
> socket.getInputStream().read();
> } finally {
> server.stop();
> }
> } }
> Throws the following exception: java.net.SocketException: No such file or
> directory
> org.apache.harmony.luni.platform.OSNetworkSystem.read(OSNetworkSystem.java)
> at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:557)
> at
> org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:61)
> at HarmonyFtpClient.main(HarmonyFtpClient.java:27)
Thanks again for the test case. I turns out it fails for me even sooner
than this because I tend to blacklist the ipv6 module on my linux
machine. It worked on Sun so we must have another bug here too.
I also spotted another "bug" where where the client socket is doing a
bind on 0.0.0.0, port 0 which is rather pointless. If it doesn't want
to use a specific address and/or port then doing a bind achieves nothing
so this should be avoided.
So there are at least three bugs found thanks to your latest email.
Fixing them might take a little while since I want to have some more
discussion of the SIGUSR2 issue[0]. If you want to track when these get
fixed, then it might be best to raise a JIRA.
Regards,
Mark.
[0] I'd like to avoid it completely rather than continue to have to work
around it.