3 Replies Latest reply on Sep 12, 2005 1:03 PM by starksm64

    JBAS-2237: Discussion


      Comment by Scott M Stark [09/Sep/05 12:13 PM] Delete
      [ Permlink ]
      The stack trace and message look consistent to me. You appear to have used an invalid naming url for the current InitialContextFactory and its parsing the host and port incorrectly because of this. Show the InitialContextFactory env/jndi.properties.

      Comment by Jens Elkner [09/Sep/05 05:01 PM] Delete
      [ Permlink ]
      Hmmm - well, the detailed message of the execption says:

      Could not obtain connection to any of these urls: https://localhost:8443/invoker/JNDIFactory and discovery failed with error: javax.naming.CommunicationException: Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out]

      BUT the stacktrace tells a DIFFERENT story ...

      The naming URL is https://localhost:8443/invoker/JNDIFactory - so should be correct. NOTE: I'm not saying, that there shouldn't be a stacktrace, I'm just saying, that the detailed message and the stacktrace do NOT correlate.

      I guess, the first stacktrace (the real reason) is swallowed up and than more or less sensless stuff tried (which might be a security issue), and finally the last stacktrace of the senseless stuff gets thrown with the initial stacktrace.toString() as message... More than strange!!!

      Comment by Adrian Brock [09/Sep/05 06:25 PM] Delete
      [ Permlink ]
      I've changed this to a feature request.

      This is better than it was before. Previously you would just get a message "lookup failed: received timeout"
      and who knows how many times that has been posted in the forums?

      We could have a policy that "complicated stuff" only gets put in the logs, but since it is too late
      after the fact to enable logging that doesn't always work. And a lot users don't even seem to be
      aware that logging exists.

      What you are seeing is multiple errors caused by the different mechanisms JBoss jndi tries to connect.
      1) Using the provider url(s)
      2) Using hajndi discovery

      All failed so you get multiple errors, with the stacktrace from the first (and probably the most pertinent
      since that it was what trying to use) error.

      It is a feature request because it could be better formatted. It certainly isn't a bug.

      If you don't want to expose your users to the "real reason" it is trivial to do
      try
      {
      object = context.lookup("blah");
      }
      catch (NamingException e)
      {
      mylog.log("real error looking up blah", e);
      throw new NamingException("cannot lookup blah");
      }

      Comment by Adrian Brock [09/Sep/05 06:31 PM] Delete
      [ Permlink ]
      "Show the InitialContextFactory env/jndi.properties."

      Do this in the forums, not here.

      Comment by Jens Elkner [10/Sep/05 05:02 PM] Delete
      [ Permlink ]
      > This is better than it was before. Previously you would just get a message
      > "lookup failed: received timeout" and who knows how many times that has been posted > in the forums?

      Hmmm, not sure, whether we are on the same subject. It is completely ok, to wrap an exception into another with a more descriptive message. What is not ok, is, to throw an unrelated Exception, with the description of a completely different Exception.

      The point is, the provider URL is in this example https://localhost:8443/invoker/JNDIFactory . This causes a receive timout exception, e.g. because the service is not running. So the thrown Exception stack should be
      ...
      javax.naming.CommunicationException: Unable to connect to localhost:8443
      java.net.SocketTimeoutException: Receive timed out

      In this case, the application designer is able to analyze the correct cause (timeout) and given an appropriate hint to the user (e.g. "make sure, 1) that the service is running, 2) you entered the correct hostname, 3) you entered the correct port", etc).

      If the root cause would be an UnknownHostException, one could warn: "Unable to resolve the hostname 'e.getMessage()'."

      With the current exception chaos wrt. the example, one would always get "Unable to resolve the hostname 'https'." - which is obviously totaly brain damaged.

      Analyzing the detailedMessage is no option, since nobody knows, whatever will show up there (now or in future). So the only thing is the real exception stack, one can rely on and BTW: not all end users are able to read/understand english - so there is a need for i18n and since the jboss doesn't do that (which is IMHO acceptable), the app developer must do the additional work. But than (again) he needs something reliable.

      IMHO jboss tries to do too much and thats why things get screwed up - since it does not know, what the application wants to do and makes wrong assumptions...

      Actually, I can't see any reason, why jboss tries to connect to a host 'https'. The Provider URL is https://localhost:1099/invoker/JNDIFactory -
      clearly: the scheme is 'https', the host is 'localhost', the port is '1099', the path '/invoker/JNDIFactory'. So, what is unclear here or can not be understood ?

      IMHO, it is easy to parse the provided URL into an URI and extract all required parts. If the scheme is missing, one can throw a Maleformed URL exception. If there is no host, well throwing an exception or using a default would be ok. If port is -1, use the default. And (which would be IMHO already too much), if scheme is http[s] and part is null, one could set the part automatically to /invoker/JNDIFactory.

      And finally, if an URI with all required parts has been constructed, one can try to connect. If this fails, the exception is wrapped into a NamingExcpetion (or CommunicationException) and rethrown. That's it - straightforward, simple and reliable. No need to try other (unsecure) stuff, which the developer actually had never in mind!

      Comment by Jens Elkner [10/Sep/05 05:05 PM] Delete
      [ Permlink ]
      > All failed so you get multiple errors, with the stacktrace from the first (and probably the > most pertinent
      > since that it was what trying to use) error.

      And this is actually really a bug, you get the message from the first, but the stacktrace from the last!!!

      Comment by Jens Elkner [10/Sep/05 07:16 PM] Delete
      [ Permlink ]
      Couldn't resist to have a look at the mess:

      e.g. jnp://localhost:1100 (wrong port)
      org.jnp.naming.interfaces.NameingContext#checkRef(props):
      ...
      // get server
      servex =
      javax.naming.CommunicationException: Failed to connect to server localhost:1100
      javax.naming.ServiceUnavailableException: Failed to connect to server localhost:1100
      java.net.ConnectException:Connection refused
      // discover server
      discoveryFailure =
      javax.naming.CommunicationException: Receive timed out
      java.net.SocketTimeoutException: Receive timed out
      // throws
      new CommunicationException("Could not obtain connection to any of these urls: localhost:1100 and discovery failed with error: javax.naming.CommunicationException: Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out]", serverex)

      So in this case, the exception stack is right, but the detailed message of the ComEx doesn't even mention the cause for the given provided URL (which is 'connection refused').

      E.g. http://localhost:8081/invoker/JNDIFactory (wrong port)
      org.jboss.naming.HttpNamingContextFactory#getInitialContext(props):
      ...
      ex = java.net.ConnectException: Connection refused
      throw new NamingException("Failed to retrieve Naming interface", ex)

      So the exception stack is right, but the detailed message doesn't mention the real cause ('connection refused') - next case, where detailed message is unusable for an enduser.

      E.g. https://localhost:8443/invoker/JNDIFactory (wrong factory (NamingContextFactory) and services is not running)
      org.jnp.naming.interfaces.NameingContext#checkRef(props)
      ...
      /* IMHO #parseNameForScheme(...) should throw an exception, since it doesn't know
      anything about 'https:', which - if ignored - in turn leads to wrong values for the
      subsequent methods (e.g. host = https - aha!, and sets the port to 1099 - oops! -
      nobody said that, we said 8443!)
      */
      // get server
      serverex =
      javax.naming.CommunicationException: Failed to connect to server https:1099
      javax.naming.ServiceUnavailableException: Failed to connect to server https:1099
      java.net.UnknownHostException: https: https
      // discover server
      discoveryFailure =
      javax.naming.CommunicationException: Receive timed out
      java.net.SocketTimeoutException: Receive timed out
      // throws
      new CommunicationException("Could not obtain connection to any of these urls: https://localhost:8443/invoker/JNDIFactory and discovery failed with error: javax.naming.CommunicationException: Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out]", serverex)

      So again, we get a detailed message, which is unusable for the enduser. But I must admit, that the provided exception stack is correct (in opposite, what I assumed earlier).

      So perhaps the RFE should be, throw an Exception, if there is scheme in the provided URL, which isn't known by jboss handler. And well, at least IMHO the default auto-discovery is quite questionable ...

        • 1. Re: JBAS-2237: Discussion

          Adrian Brock's 5th law of programming:

          "You cannot make anything fool proof - fools are such inventive people".
          Or in this context: GIGO

          We could of course try to trap every possible stupid misconfiguration,
          but then the code would 99% error checking to cater for people that can't
          follow basic documentation.
          i.e. https:// needs the Http NamingContextFactory

          The throwing the last exception rather the first, sounds like a bug.

          • 2. Re: JBAS-2237: Discussion

            Related Issue:

            We really need to expand on this Feature Request:
            http://jira.jboss.com/jira/browse/JBAS-1839
            to review all the error checking/logging in naming.
            Not just a lookup.

            • 3. Re: JBAS-2237: Discussion
              starksm64

              To me this is just an issue of inconsistent evolution of the single protocol, single connection jndi naming context factory to a multiple protocol, multiple connection version with on the fly behavior change due to discovery. The behavior of connection establishment and failure reporting needs to be refactored in light of this.

              The most obvious problem is the inconsistent handling of a url presented to an InitialContextFactory implementation showing up as something the NamingContext attempts to parse, but does not understand.