Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.6, JRuby 1.6.7
    • Fix Version/s: JRuby 1.7.0.pre1
    • Component/s: None
    • Labels:
      None
    • Number of attachments :
      0

      Description

      Code: https://github.com/jordansissel/experiments/blob/master/ruby/sockets/listen.rb

      % ruby listen.rb 
      NoMethodError: undefined method `accept' for #<Socket:0x52c4c57>
        (root) at listen.rb:12
      
      % ruby --1.9 listen.rb
      NoMethodError: undefined method `accept' for #<Socket:fd 6>
        (root) at listen.rb:12
      

      Here's a breakdown of looking for Socket#accept on various rubies:

      {:version=>"1.8.7 @ jruby-1.6.5", :has_accept?=>false}
      {:version=>"1.8.7 @ jruby-1.6.6", :has_accept?=>false}
      {:version=>"1.8.7 @ jruby-1.6.7", :has_accept?=>false}
      {:version=>"1.8.7 @ ruby", :has_accept?=>true}
      {:version=>"1.9.2 @ jruby-1.6.5", :has_accept?=>false}
      {:version=>"1.9.2 @ jruby-1.6.6", :has_accept?=>false}
      {:version=>"1.9.2 @ jruby-1.6.7", :has_accept?=>false}
      {:version=>"1.9.2 @ ruby", :has_accept?=>true}
      {:version=>"1.9.3 @ ruby", :has_accept?=>true}
      

      Thoughts?

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        The reason we have never implemented this is because the JDK separates server from client sockets at construct time. We can't open a socket first and then decide it will act as a server later. We must make that decision when we construct the object that actually opens up an fd.

        The question for me has always been this: why can't a user decide that it's a ServerSocket when they're opening it?

        I'll poke around and see if anything has changed in the JDK APIs we use, but that's the short story.

        Show
        Charles Oliver Nutter added a comment - The reason we have never implemented this is because the JDK separates server from client sockets at construct time. We can't open a socket first and then decide it will act as a server later. We must make that decision when we construct the object that actually opens up an fd. The question for me has always been this: why can't a user decide that it's a ServerSocket when they're opening it? I'll poke around and see if anything has changed in the JDK APIs we use, but that's the short story.
        Hide
        Charles Oliver Nutter added a comment -

        More concrete pointers...

        At socket create time, we need to either create one of these:

        http://docs.oracle.com/javase/6/docs/api/java/nio/channels/SocketChannel.html

        or one of these:

        http://docs.oracle.com/javase/6/docs/api/java/nio/channels/ServerSocketChannel.html

        At one point we debated possibly deferring the creation of the actual channel until the user picks connect or accept, but then we're not actually allocating the fd, can't set flags, etc. It becomes pretty message to defer the creation, since a lot of other pre-connect/accept methods still need to work, and may cause us to force it into existence before we know if it will do a connect or an accept.

        Show
        Charles Oliver Nutter added a comment - More concrete pointers... At socket create time, we need to either create one of these: http://docs.oracle.com/javase/6/docs/api/java/nio/channels/SocketChannel.html or one of these: http://docs.oracle.com/javase/6/docs/api/java/nio/channels/ServerSocketChannel.html At one point we debated possibly deferring the creation of the actual channel until the user picks connect or accept, but then we're not actually allocating the fd, can't set flags, etc. It becomes pretty message to defer the creation, since a lot of other pre-connect/accept methods still need to work, and may cause us to force it into existence before we know if it will do a connect or an accept.
        Hide
        Charles Oliver Nutter added a comment -

        Ok, I have a workaround I'm considering shipping with JRuby 1.7. I added "ServerSocket".

        The logic is pretty much the same as for using Socket like you want, but instead you'd use ServerSocket and it will have an "accept" method. It's a simple change for your code, and to make it compatible with MRI you can just set ServerSocket = Socket.

        Does that sound reasonable?

        Show
        Charles Oliver Nutter added a comment - Ok, I have a workaround I'm considering shipping with JRuby 1.7. I added "ServerSocket". The logic is pretty much the same as for using Socket like you want, but instead you'd use ServerSocket and it will have an "accept" method. It's a simple change for your code, and to make it compatible with MRI you can just set ServerSocket = Socket. Does that sound reasonable?
        Hide
        Charles Oliver Nutter added a comment -

        Ok, I added ServerSocket on master in the folllowing commit. I'd appreciate you giving it a shot, and I'll look into whether existing tests can be used to confirm it's functioning properly (may be hard since they all use Socket and not ServerSocket).

        commit d5a87bf2d6e8458ba0c0e35149ab0132d576efe9
        Author: Charles Oliver Nutter <headius@headius.com>
        Date:   Tue Mar 6 16:21:48 2012 -0600
        
            Fix JRUBY-6526 and continue socket refactoring.
            
            * Moved most Socket class methods to SocketUtils
            * Added ServerSocket as a JRuby workaround for Socket only being clients
            * Added support for symbolic domain, type, and protocol (1.9)
            * Added 1.9 Socket#initialize with two args
        
        Show
        Charles Oliver Nutter added a comment - Ok, I added ServerSocket on master in the folllowing commit. I'd appreciate you giving it a shot, and I'll look into whether existing tests can be used to confirm it's functioning properly (may be hard since they all use Socket and not ServerSocket). commit d5a87bf2d6e8458ba0c0e35149ab0132d576efe9 Author: Charles Oliver Nutter <headius@headius.com> Date: Tue Mar 6 16:21:48 2012 -0600 Fix JRUBY-6526 and continue socket refactoring. * Moved most Socket class methods to SocketUtils * Added ServerSocket as a JRuby workaround for Socket only being clients * Added support for symbolic domain, type, and protocol (1.9) * Added 1.9 Socket#initialize with two args
        Charles Oliver Nutter made changes -
        Field Original Value New Value
        Fix Version/s JRuby 1.7 [ 17049 ]
        Hide
        Charles Oliver Nutter added a comment -

        FWIW, the shortest-term workaround is to just use TCPServer when you need a server.

        Show
        Charles Oliver Nutter added a comment - FWIW, the shortest-term workaround is to just use TCPServer when you need a server.
        Hide
        Charles Oliver Nutter added a comment -

        To make it easier for others to find ServerSocket in the future, I've added an #accept impl to Socket that just errors and points users to ServerSocket at http://wiki.jruby.org/ServerSocket.

        commit 7fb8ea02a5292b6a64de218253b756e1c14c61fb
        Author: Charles Oliver Nutter <headius@headius.com>
        Date:   Tue Mar 6 23:44:50 2012 -0600
        
            Add error message for Socket#accept.
            
            Because we can't support both client and server connections in
            Socket, we have added ServerSocket for the server side. To make
            this easier to find, I've added an impl of Socket#accept that
            mentions ServerSocket and links to an informational page on the
            JRuby wiki.
        
        Show
        Charles Oliver Nutter added a comment - To make it easier for others to find ServerSocket in the future, I've added an #accept impl to Socket that just errors and points users to ServerSocket at http://wiki.jruby.org/ServerSocket . commit 7fb8ea02a5292b6a64de218253b756e1c14c61fb Author: Charles Oliver Nutter <headius@headius.com> Date: Tue Mar 6 23:44:50 2012 -0600 Add error message for Socket#accept. Because we can't support both client and server connections in Socket, we have added ServerSocket for the server side. To make this easier to find, I've added an impl of Socket#accept that mentions ServerSocket and links to an informational page on the JRuby wiki.
        Hide
        Charles Oliver Nutter added a comment -

        Marking this resolved. We can't support #accept directly on Socket, but I think the ServerSocket class is a pretty good workaround.

        Show
        Charles Oliver Nutter added a comment - Marking this resolved. We can't support #accept directly on Socket, but I think the ServerSocket class is a pretty good workaround.
        Charles Oliver Nutter made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Assignee Thomas E Enebo [ enebo ] Charles Oliver Nutter [ headius ]
        Resolution Fixed [ 1 ]

          People

          • Assignee:
            Charles Oliver Nutter
            Reporter:
            Jordan Sissel
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: