java 1.5 InetAddr doesn't consult system hosts file unless run from [pseudo]tty?

Discussion in 'Java' started by trawick@gmail.com, Nov 15, 2006.

  1. Guest

    A simple test program can look up hostnames defined in system host file
    as long as it is run with a tty. When run without a tty, it can't find
    the hostnames. This issue leads to the failure of an application when
    run remotely.

    Various properties tweaked; seen on AIX and Linux/PPC too with
    IBM-supplied java 1.5; recreated below with current Sun java 1.5 for
    Solaris; an application which has the same issue with java 1.5 ran for
    ages with java 1.4.2 on many platforms with no such issue

    Has anybody seen anything similar?

    >From a Solaris 9 run with freshly downloaded/untweaked jre 1.5:


    $ cat /etc/inet/ipnodes
    #
    # Internet host table
    #
    #::1 localhost
    ::1 ipv6host
    127.0.0.1 ipv4host

    $ cat useinetaddr.sh
    #!/bin/sh

    PATH=$HOME/jre1.5.0_09/bin:$PATH
    export PATH

    java -version

    java UseInetAddr ipv4host
    java UseInetAddr ipv6host

    $ cat UseInetAddr.java
    import java.net.InetAddress;

    public class UseInetAddr {

    public static void main(String[] args) throws Exception {
    InetAddress inetAddr;

    System.out.println("looking up " + args[0] + "...");
    inetAddr = InetAddress.getByName(args[0]);
    System.out.println("okay");
    }
    }

    Run it directly from remote terminal... no problems

    $ ./useinetaddr.sh
    java version "1.5.0_09"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
    Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing)
    looking up ipv4host...
    okay
    looking up ipv6host...
    okay

    Run it via ssh to self... fails to find the definition

    $ ssh 127.0.0.1 ./useinetaddr.sh
    java version "1.5.0_09"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
    Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing)
    looking up ipv4host...
    Exception in thread "main" java.net.UnknownHostException: ipv4host:
    ipv4host
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getByName(Unknown Source)
    at UseInetAddr.main(UseInetAddr.java:9)
    looking up ipv6host...
    Exception in thread "main" java.net.UnknownHostException: ipv6host:
    ipv6host
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getByName(Unknown Source)
    at UseInetAddr.main(UseInetAddr.java:9)

    Run it via ssh to self, but tell ssh to allocate a pseudoterminal using
    ssh -t option... works...

    $ ssh -t 127.0.0.1 ./useinetaddr.sh
    java version "1.5.0_09"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
    Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing)
    looking up ipv4host...
    okay
    looking up ipv6host...
    okay
    Connection to 127.0.0.1 closed.
    , Nov 15, 2006
    #1
    1. Advertising

  2. On 15 Nov 2006 06:56:55 -0800, wrote:
    > A simple test program can look up hostnames defined in system host file
    > as long as it is run with a tty. When run without a tty, it can't find
    > the hostnames. This issue leads to the failure of an application when
    > run remotely.


    I'm unable to reproduce this error using 1.5.0_09 on Linux or 1.5.0_08
    on Solaris 10, however I suspect that the different behaviour can be
    explained by differences in the environment set up by your shell in
    the two cases.

    E.g. what happens when you run these commands:

    $ ssh localhost /usr/ucb/printenv
    $ ssh -t localhost /usr/ucb/printenv

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Nov 15, 2006
    #2
    1. Advertising

  3. Guest

    Gordon Beaton wrote:
    > On 15 Nov 2006 06:56:55 -0800, wrote:
    > > A simple test program can look up hostnames defined in system host file
    > > as long as it is run with a tty. When run without a tty, it can't find
    > > the hostnames. This issue leads to the failure of an application when
    > > run remotely.

    >
    > I'm unable to reproduce this error using 1.5.0_09 on Linux or 1.5.0_08
    > on Solaris 10, however I suspect that the different behaviour can be
    > explained by differences in the environment set up by your shell in
    > the two cases.


    First, thanks for taking an interest! I had considered envvars before
    and didn't come up with any key difference (see below). Also, I saved
    envvars from a working environment and changed the env table to match
    exactly when run via ssh, all with no happiness.

    > E.g. what happens when you run these commands:
    >
    > $ ssh localhost /usr/ucb/printenv
    > $ ssh -t localhost /usr/ucb/printenv


    $ ssh 127.0.0.1 /usr/ucb/printenv >envvars.notty
    $ ssh -t 127.0.0.1 /usr/ucb/printenv >envvars.tty
    Connection to 127.0.0.1 closed.
    $ diff -ub envvars.notty envvars.tty
    --- envvars.notty Wed Nov 15 10:48:13 2006
    +++ envvars.tty Wed Nov 15 10:48:18 2006
    @@ -9,6 +9,7 @@
    HOSTTYPE=sparc
    OSTYPE=solaris2.9
    HOME=/home/trawick
    -TERM=dumb
    +TERM=xterm
    PATH=/usr/bin:/bin:/usr/sbin:/sbin
    +SSH_TTY=/dev/pts/3
    _=/usr/ucb/printenv

    FWIW, I just checked if changing my login shell from /usr/bin/bash to
    /bin/sh would help. But it didn't.
    , Nov 15, 2006
    #3
  4. Guest

    Gordon Beaton wrote:
    > On 15 Nov 2006 06:56:55 -0800, wrote:
    > > A simple test program can look up hostnames defined in system host file
    > > as long as it is run with a tty. When run without a tty, it can't find
    > > the hostnames. This issue leads to the failure of an application when
    > > run remotely.

    >
    > I'm unable to reproduce this error using 1.5.0_09 on Linux or 1.5.0_08
    > on Solaris 10...


    Even though I've encountered the problem on several platforms with
    different levels of Java 1.5, your failure to recreate promped the
    thought that the failure is related to some common setting I apply to
    my user id. I created a new user id on the Solaris 9 system, but it
    still failed.
    , Nov 15, 2006
    #4
  5. Guest

    wrote:
    > A simple test program can look up hostnames defined in system host file
    > as long as it is run with a tty. When run without a tty, it can't find
    > the hostnames. This issue leads to the failure of an application when
    > run remotely.


    I compared truss of both runs. Here's what happens between loading
    java libnet.so and making the door call to the resolver:

    Good run (stdin is a terminal):

    531/1: so_socket(PF_INET6, SOCK_STREAM, IPPROTO_IP, "", 1) = 5
    Is this next line nonsense because it is calling getsockname() on
    the wrong descriptor or nonsense because this resolver interface code
    shouldn't care whether or not FILE_STDIN is a socket? Either way, this
    error path from getsockname() is apparently related to the testcase
    working.
    531/1: getsockname(0, 0xFFBFDCEC, 0xFFBFDD0C, 1) Err#95
    ENOTSOCK
    531/1: ioctl(5, 0xC00C6982, 0xFFBFDCE0) = 0
    531/1: close(5) = 0
    531/1:
    stat64("/home/trawick/jre1.5.0_09/lib/security/java.security",
    0xFFBFC688) = 0
    531/1:
    open64("/home/trawick/jre1.5.0_09/lib/security/java.security",
    O_RDONLY) = 5
    531/1: fstat64(5, 0xFFBFC5F8) = 0
    531/1: read(5, " #\n # T h i s i s ".., 8192) = 8192
    531/1: lwp_cond_signal(0x000365D0) = 0
    531/6: lwp_cond_wait(0x000365D0, 0x000365B8, 0x00000000) = 0
    531/6: lwp_mutex_lock(0x000365B8) = 0
    531/6: lwp_schedctl(SC_PREEMPT, 0, 0xFB77EA04) = 0
    531/6: lwp_self() = 6
    531/6: lwp_schedctl(SC_PREEMPT, 0, 0xFB77EA04) = 0
    531/6: lwp_self() = 6
    531/6: brk(0x0011FEA0) = 0
    531/6: brk(0x00127EA0) = 0
    531/6: brk(0x00127EA0) = 0
    531/6: brk(0x0012FEA0) = 0
    531/1: lwp_mutex_wakeup(0x000365B8) = 0
    531/1: read(5, " f t h e c e r t i f".., 8192) = 2057
    531/1: fstat64(5, 0xFFBFC450) = 0
    531/1: llseek(5, 0, SEEK_CUR) = 10249
    531/1: llseek(5, 0, SEEK_END) = 10249
    531/1: llseek(5, 10249, SEEK_SET) = 10249
    531/1: read(5, 0xFFBFA440, 8192) = 0
    531/1: close(5) = 0
    531/8: poll(0x00000000, 0, 50) = 0
    531/1: open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 5
    531/1: fcntl(5, F_DUPFD, 0x00000100) = 256
    531/1: close(5) = 0
    531/1: read(256, " # p r a g m a i d e n".., 1024) = 1024
    531/1: read(256, " t s t p i _ c".., 1024) = 215
    531/1: read(256, 0x0012E258, 1024) = 0
    531/1: lseek(256, 0, SEEK_SET) = 0
    531/1: read(256, " # p r a g m a i d e n".., 1024) = 1024
    531/1: read(256, " t s t p i _ c".., 1024) = 215
    531/1: read(256, 0x0012E258, 1024) = 0
    531/1: close(256) = 0
    531/1: open("/dev/udp", O_RDONLY) = 5
    531/1: ioctl(5, 0xC00C6982, 0xFFBFE8FC) = 0
    531/1: close(5) = 0
    531/1: door_info(4, 0xFFBFC880) = 0
    531/1: door_call(4, 0xFFBFC868) = 0
    531/1: write(1, " o k a y", 4) = 4
    531/1: write(1, "\n", 1) = 1

    Failing run (stdin is not a terminal):

    512/1: so_socket(PF_INET6, SOCK_STREAM, IPPROTO_IP, "", 1) = 5
    Note that this getsockname(FILENO_STDIN) succeeds. But why does it
    matter?
    512/1: getsockname(0, 0xFFBFDD04, 0xFFBFDD24, 1) = 0
    512/1:
    stat64("/home/trawick/jre1.5.0_09/lib/security/java.security",
    0xFFBFC6A0) = 0
    512/1:
    open64("/home/trawick/jre1.5.0_09/lib/security/java.security",
    O_RDONLY) = 6
    512/1: fstat64(6, 0xFFBFC610) = 0
    512/1: read(6, " #\n # T h i s i s ".., 8192) = 8192
    512/1: lwp_cond_signal(0x000365D0) = 0
    512/6: lwp_cond_wait(0x000365D0, 0x000365B8, 0x00000000) = 0
    512/6: lwp_mutex_lock(0x000365B8) = 0
    512/6: lwp_schedctl(SC_PREEMPT, 0, 0xFB77EB84) = 0
    512/6: lwp_self() = 6
    512/6: lwp_schedctl(SC_PREEMPT, 0, 0xFB77EB84) = 0
    512/6: lwp_self() = 6
    512/6: brk(0x0011FEA0) = 0
    512/6: brk(0x00127EA0) = 0
    512/6: brk(0x00127EA0) = 0
    512/6: brk(0x0012FEA0) = 0
    512/1: lwp_mutex_wakeup(0x000365B8) = 0
    512/1: read(6, " f t h e c e r t i f".., 8192) = 2057
    512/1: fstat64(6, 0xFFBFC468) = 0
    512/1: llseek(6, 0, SEEK_CUR) = 10249
    512/1: llseek(6, 0, SEEK_END) = 10249
    512/1: llseek(6, 10249, SEEK_SET) = 10249
    512/1: read(6, 0xFFBFA458, 8192) = 0
    512/1: close(6) = 0
    512/1: open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 6
    512/1: fcntl(6, F_DUPFD, 0x00000100) = 256
    512/1: close(6) = 0
    512/1: read(256, " # p r a g m a i d e n".., 1024) = 1024
    512/1: read(256, " t s t p i _ c".., 1024) = 215
    512/1: read(256, 0x0012E250, 1024) = 0
    512/1: lseek(256, 0, SEEK_SET) = 0
    512/1: read(256, " # p r a g m a i d e n".., 1024) = 1024
    512/1: read(256, " t s t p i _ c".., 1024) = 215
    512/1: read(256, 0x0012E250, 1024) = 0
    512/1: close(256) = 0
    512/1: open("/dev/udp", O_RDONLY) = 6
    512/1: ioctl(6, 0xC00C6982, 0xFFBFE72C) = 0
    512/1: close(6) = 0
    512/1: door_info(4, 0xFFBFC6B0) = 0
    512/8: poll(0x00000000, 0, 50) = 0
    512/1: door_call(4, 0xFFBFC698) = 0
    512/1: write(2, " E x c e p t i o n i n".., 27) = 27

    Now tweak the shell script so that stdin isn't a socket even when ssh
    doesn't allocate a tty:

    $ cat useinetaddr2.sh
    #!/bin/sh

    PATH=$HOME/jre1.5.0_09/bin:$PATH
    export PATH

    java -version

    java UseInetAddr ipv4host </dev/null
    java UseInetAddr ipv6host </dev/null

    $ ssh 127.0.0.1 ./useinetaddr2.sh
    java version "1.5.0_09"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
    Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing)
    looking up ipv4host...
    okay
    looking up ipv6host...
    okay

    Groan!
    , Nov 15, 2006
    #5
  6. On 15 Nov 2006 10:35:47 -0800, wrote:
    > I compared truss of both runs. Here's what happens between loading
    > java libnet.so and making the door call to the resolver:


    I really don't have any concrete suggestions here, but maybe this will
    give you some ideas...

    I don't use Solaris much these days, but my understanding is that
    /etc/inet/ipnodes was added to provide support for ipv6 addresses, and
    that the resolver falls back to /etc/hosts when an entry isn't found
    (but don't quote me on this). Is ipnodes still used if you haven't
    enabled ipv6 support on your system?

    Do you see similar behaviour if you write a short C program that uses
    gethostbyname() or getipnode()? What if you put the hostname in
    /etc/hosts instead of /etc/inet/ipnodes?

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Nov 16, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bla
    Replies:
    0
    Views:
    2,842
  2. Piotre Ugrumov

    How do I consult a XML document?

    Piotre Ugrumov, Jan 20, 2004, in forum: Java
    Replies:
    1
    Views:
    316
    Christophe Vanfleteren
    Jan 20, 2004
  3. Gábor SEBESTYÉN

    Unless unless

    Gábor SEBESTYÉN, Jun 17, 2005, in forum: Ruby
    Replies:
    3
    Views:
    136
    Gábor SEBESTYÉN
    Jun 17, 2005
  4. Bla
    Replies:
    1
    Views:
    193
    Tad McClellan
    Apr 10, 2005
  5. Replies:
    0
    Views:
    117
Loading...

Share This Page