1

ADDED 7/23.

Many views: Not even a "that's dumb" question in response. Can anyone at least tell me why such an embarrassingly trivial question seems to have no answer anywhere.

Q:

--- Have Wildfly 8 running on local machine localhost:9990. --- Have a Java program that need's Wildfly's IntialContext. --- Every reference says use: "Context ctx = new InitialContext(env);" --- Yet a week of searching turns up no set of properties that returns one. And no example of a java program that gets one.

Does no one ever do this? Really need help

Original Msg Below

I know many people have asked how to get an Initial context from Wildfly 8. But I have yet to find a simple answer with a simple example.

Therefore, I hope someone can tell my why this doesn’t work. I start Wildfly with standalone-full.xml

The three sections below have

A - Code summary of my test Class whose only purpose is to secure an Initial Context. (I only removed a lot of printing code that produced the next section.]

B - The Eclipse console output for a failure.

C - Cut and paste code. Just in case anyone can help me get this to work. I’d like to leave behind something the next new WF user can cut and past and run. The only difference from 1 above is that this version has all the static methods I used to format the output. NOTE: I know the comments I inserted about the less than sign sound dumb. BUT ... they are true.

A Code Summary

import java.util.Properties;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.InitialContext;
public class JmsTestGetJNDIContext {

  //members
  final private Properties env = new Properties() {
    private static final long serialVersionUID = 1L;
    {
      /* These are Properties used by a standalone JavaClient to secure a WIldFly InitialContext()*/             
      put(Context.INITIAL_CONTEXT_FACTORY,   "org.jboss.naming.remote.client.InitialContextFactory");  
      put(Context.PROVIDER_URL,"http-remoting://localhost:9990");
      put(Context.SECURITY_PRINCIPAL,"userGLB");  
      put(Context.SECURITY_CREDENTIALS,"Open");
      put("jboss.naming.client.ejb.context", true);  

      /*The above URL, ID and PW successfully open Wildfly's Admin Console*/
    }
  };

  //constructor
  private JmsTestGetJNDIContext (){
    /*print "beg"*/
    /*print "env"*/
    try { 
      /*print "Requesting InitialContext"*/
      Context ctx = new InitialContext(this.env); 
      /*print "JNDI Context: " + ctx)*/
      /*print "end");
    } catch (CommunicationException e) {
      /* print "You forgot to start WildFly dummy!"*/       
    } catch (Exception e) {
      /* print"caught:  " + e.getClass().getName()*/
      /*print e.getMessage()*/
      /* "end")*/
    }
    static public void main (String[] args) {
     /*print "beg"*/
     JmsTestGetJNDIContext client = new JmsTestGetJNDIContext ();
     /*print "end"*/
    }
  }

B - Console Output

JmsTestGetJNDIContext.main ()   beg
  JmsTestGetJNDIContext.<init> ()       beg
    JmsTestGetJNDIContext.<init> ()       These are Properties used to obtain IntialContext
           Key: java.naming.provider.url
                Value: http-remoting://localhost:9990
           Key: java.naming.factory.initial
                Value: org.jboss.naming.remote.client.InitialContextFactory
           Key: jboss.naming.client.ejb.context
                Value: true
           Key: java.naming.security.principal
                Value: userGLB
           Key: java.naming.security.credentials
                Value: Open
    JmsTestGetJNDIContext.<init> ()       Requesting InitialContext
    JmsTestGetJNDIContext.<init> ()       caught: javax.naming.NamingException
    JmsTestGetJNDIContext.<init> ()       Failed to create remoting connection
  JmsTestGetJNDIContext.<init> ()       end
JmsTestGetJNDIContext.main ()   end

Cut and Paste Code

package org.america3.gotest.xtra;
import java.util.Properties;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.InitialContext;
public class JmsTestGetJNDIContext {
//members
final private Properties env = new Properties() {
  /**
   * Properties used by a standalone JavaClient to secure
   * a WIldFly InitialContext()*/
  private static final long serialVersionUID = 1L;
    {
put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");  
      put(Context.PROVIDER_URL, "http-remoting://localhost:9990");
      put(Context.SECURITY_PRINCIPAL, "userGLB");  
      put(Context.SECURITY_CREDENTIALS, "Open");
      // The above URL, ID and PW successfully open Wildfly's Admin Console
      put("jboss.naming.client.ejb.context", true);  
    }
  };
  //constructor
  private JmsTestGetJNDIContext (){/*ignore*/String iAm = JmsTestGetJNDIContext.getIAm("  ", Thread.currentThread().getStackTrace()); 
  P (iAm, "beg");
  pProps(iAm, env);
  try { 
    P (sp + iAm, "Requesting InitialContext");
    Context ctx = new InitialContext(this.env); 
    P (sp + iAm, "JNDI Context: " + ctx);
     P (sp + iAm, "end");
  } catch (CommunicationException e) {
    P (sp +  iAm, "You forgot to start WildFly dummy!");       
  } catch (Exception e) {
    P (sp + iAm, "caught:  " + e.getClass().getName());
    P (sp + iAm, e.getMessage());
    P (iAm, "end");
  }
}
static public void main (String[] args) {/*ignore*/String iAm =  JmsTestGetJNDIContext.getIAm("",Thread.currentThread().getStackTrace());
  P (iAm, "beg");
  JmsTestGetJNDIContext client = new JmsTestGetJNDIContext ();
  P (iAm , "end");
}

/*The remaining static methods are just to facilitate printing.
 * They are normally in a Untility package I add to my projects.
 * I put them here so this code would run for anyone.*/

  static private void pProps (String leader, Properties p) {
    StringBuffer sb = new StringBuffer ();
    String s = JmsTestGetJNDIContext.padRight(leader, 45, ' ');
    s = "  " + s + "These are Properties used to obtain IntialContext"+"\n";
    sb.append(s);
    String skip = "";
    for (Object key: p.keySet()) {
      sb.append(skip + "       " + JmsTestGetJNDIContext.padRight("\"" 
                   + (String)key + "\"", 40, ' ') 
                   + "     \"" + p.get(key) + "\"");
      skip = "\n";
    }
    System.out.println(sb);
  }

  static private void P (String s, String s2) {
    System.out.println(s + s2);
  }

  static public String getClassMethodName (StackTraceElement[] elements) {
    String className = null;
    for (int i = 0; i * elements.length; i++]i ) {
      /* You need to type in a less than sign for the '*' 
       * because when I do, the editor will not show any code 
       * that comes after it.
       * I have no idea why, but I've spent over an hour trying,
       * and every time I type a less than sign all the following 
       * code dissappears!*/
      className = elements[i].getClassName ();
      if (className.startsWith ("org.america3")) {
        int end = className.lastIndexOf ('.');
        return className.substring (end + 1) + "." + elements[i].getMethodName ();
      } else {
        continue;
      }
    }
    return "no project method found in elements beginning with org.america3" ;
  }

  static private String getIAm (String indent, StackTraceElement[] elements) {
    StringBuffer sb = new StringBuffer ();
    sb.append(JmsTestGetJNDIContext.getClassMethodName(elements));
    sb.append(" ()");
    return indent + JmsTestGetJNDIContext.padRight (sb.toString(), 45, ' ') ;
  }

  static public String padRight(String s, int width, char c){
    if (s == null) return "Null String";
    if(s.length() ** width){
    /* You need to type in a greater than or equal sign for 
     * the '**'see above.*/
     return s;
    } else {
      StringBuffer sb = new StringBuffer();
      sb.append (s);
      for(int i = 0; i *** (width - s.length()); i++){
        /*You need to type in a less than sign the '***'. Again see above*/
        sb.append(c);
      }
      return sb.toString();
    }
  }

  static public String sp = "  ";
}
George
  • 509
  • 2
  • 9
  • 25
  • Did you change the http port to `9990`? By default that is the management http port. – James R. Perkins Jul 24 '17 at 21:23
  • The properties above includeput(Context.PROVIDER_URL,"http-remoting://localhost:9990"); Is there anyplace else to put it? – George Jul 25 '17 at 23:15
  • Port 9990 is the management port. You might want to try 8080. – James R. Perkins Jul 26 '17 at 16:16
  • Grin ... bin there done that. I tried 8080. I tried guest/guest for ID/PW. The example uses userGLB/Open. I used the CLI to create a new user and pw and tried them. No change. Also please note ... when I look at the WildFly console (and server log) after a failure there is Nothing there. No response at all. So WF is not even hearing that my java program is asking for a connection. It seems like it should be a five minute project to write a main () method that would connect to a WF running on the same computer. This seems nutz. – George Jul 27 '17 at 18:45

4 Answers4

2

A while ago I also struggled with remote EJBs in my CLI application. I excavated a small example project that I wrote then. It gets an InitialContext and calls a remote EJB named AddBrackets:

import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import de.dnb.test.ejb.AddBrackets;

public final class Application {

  public static void main(String[] args) throws NamingException {
    final Properties jndiProperties = initJndiProperties();
    final AddBrackets addBrackets = getEjb(jndiProperties);

    System.out.println(addBrackets.processText("Hello World"));
  }

  private static Properties initJndiProperties() {
    final Properties jndiProperties = new Properties();
    jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,
        "org.jboss.naming.remote.client.InitialContextFactory");
    jndiProperties.put("jboss.naming.client.ejb.context", true);
    jndiProperties.put(Context.PROVIDER_URL, "http-remoting://localhost:8080/");
    //jndiProperties.put(Context.SECURITY_PRINCIPAL, "test");
    //jndiProperties.put(Context.SECURITY_CREDENTIALS, "test");
    return jndiProperties;
  }

  private static AddBrackets getEjb(Properties jndiProps)
      throws NamingException {
    final Context jndiContext = new InitialContext(jndiProps);
    final String interfaceName = AddBrackets.class.getName();
    return (AddBrackets) jndiContext.lookup(
        "ejbtest-app-1.0-SNAPSHOT/ejbtest-ejb-1.0-SNAPSHOT/AddBracketsBean!"
            + interfaceName);
  }
}

I built this program as a Maven project which had a dependency on

<dependency>
    <groupId>org.wildfly</groupId>
    <artifactId>wildfly-ejb-client-bom</artifactId>
    <version>8.2.1.Final</version>
    <type>pom</type>
</dependency>

This dependency brings in Wildfly's remote client EJB implementation and adds the following jars to the class path (links are to Maven Central):

I did no special configuration on Wildfly to run this example. I simply downloaded a vanilla Wildfly 8.2.1, unzipped it, set up an admin user with the add-user.sh script and deployed my EJB in an EAR. As you can see above access is granted without a username and a password.

You can find the complete project including the AddBrackets EJB on my bitbucket account.

When I tried to get my head around remote EJBs with Wildfly, I found the article JBoss EAP / Wildfly – Three ways to invoke remote EJBs really helpful. It clearly describes the three different methods to access remote EJBs on Wildfly.

Christoph Böhme
  • 3,766
  • 1
  • 19
  • 29
  • Hi Christoph. I've seen the 3-ways article, but it is focused on invoking EJB and the article mostly assumed getting a JNDI was a trivial first step. And logically getting one should be. Just isn't for me. I'll give your code a try. But since I'm not a Maven user, I'm hoping that Maven only added jar files or something else It would be hard to add directly. It may take a day or so before I can tell if this works and get back to you.. I'm obviously missing something that should be obvious. Getting a JNDI Initial context shouldn't really involve rocket science. Thanx – George Jul 29 '17 at 22:04
  • Sorry Christoph. Your code produced an Identicla NoSuchMethodError. But I've found other stuff that makes me believe this is not a code problem. So I'm going to add an "Answer Your Own Question" to say why. Then close thread if I can. And start a new post focused on the real problem I'll add next. – George Jul 30 '17 at 02:07
  • No problem. At least my code showed that it was not a problem in the code. I have edited my answer now and added the list of jars on the class path. – Christoph Böhme Jul 30 '17 at 15:58
0

I’ve decided the problem isn’t coding or the JNDI InititialContext Properties.

I mean the fatal error is a NoSuchMethodError. Therefore, as I confirmed in the WildFly server logs, my main method never even tries to connect.

Here’s what I think explains the real problem.

And I think it explains why there are so many calls for help with this error:

java.lang.NoSuchMethodError:
org.jboss.remoting3.Remoting.createEndpoint(Ljava/lang/String;Lorg/xnio/OptionMap;)Lorg/jboss/remoting3/Endpoint;]

Also why none of those calls for help ever get a conclusive answer. Just people suggesting different jars.

And since all those answers fixed on jars, this is how I tested the Build Path I was using:

First I removed all jars from the Build Path. Then I ran my one line main program till all ClassNotFoundException were gone.

First Error

java.lang.ClassNotFoundException:
org.jboss.naming.remote.client.InitialContextFactory]

Added jboss-remote-naming-1.0.7.final.jar to class path

Next Error

java.lang.NoClassDefFoundError:
org/jboss/logging/Logger

Added jboss-logging.jar

Next Error

java.lang.NoClassDefFoundError: 
org/xnio/Options

Added xnio-api-3.0.7.ga.jar

Next Error

java.lang.NoClassDefFoundError:
org/jboss/remoting3/spi/ConnectionProviderFactory

Added jboss-remoting-3.jar

Next Error

java.lang.NoClassDefFoundError:
org/jboss/ejb/client/EJBClientContextIdentifier

Added jboss-ejb-client-1.0.19.final.jar

FATAL ERROR (note: All NoClassDefFoundError have been cleared)

java.lang.NoSuchMethodError: 
org.jboss.remoting3.Remoting.createEndpoint(Ljava/lang/String;Lorg/xnio/OptionMap;)Lorg/jboss/remoting3/Endpoint;]

Then I used Eclipse’s Project Explorer to verify:

That jboss-remoting3.jar has the org.jboss.remoting3.Remoting Class. It does. That’s why there is no NoClassDefFoundError left above.

And verified it had this method: public Endpoint createEndpoint (String, Executor, OptionMap) note: 3 parameters.

BUT the above Error indicates something is calling: public Endpoint createEndpoint (String, OptionMap) note: 2 parameters.

That’s why the program throws a NoSuchMethodError. It is looking for a 2 paramater version of org.jboss.remoting3.Remoting.createEndpoint(). And the Remoting Class I have only has a 3 parameter version.`

I know this sounds impossible but the only thing I can think is there is an inconsistency in the Java API???

Clearly something is calling org.jboss.remoting3.Remoting.createEndpoint with 2 parameters.

But my org.jboss.remoting3.Remoting Class only has a 3 parameter version of the createEndpoint() Method.

So I’m going to clean this all up and repost a question asking how to explain the existence of a Class calling for a 2 paramter org.jboss.remoting3.Remoting.createEndpoint Method when I have a jar whose org.jboss.remoting3.Remoting only offers a 3-parameter.

George
  • 509
  • 2
  • 9
  • 25
  • `Remoting.createEndpoint()` in the jboss-remoting jar is called from `org.jboss.naming.remote.client.EndpointCache` in the jboss-remote-naming jar. The 2-parameter version of `createEndpoint()` was only added in version 3.2 of jboss-remoting. The [pom.xml](https://github.com/jbossas/jboss-remote-naming/blob/1.0.7.Final/pom.xml#L48) for jboss-remote-naming-1.0.7.final says it depends on jboss-remoting 3.2.7.GA. As there is no version number on your jboss-remoting jar, I suppose its an older version. Can you have a look in your jar if there is a pom.xml in META-INF with contains version number? – Christoph Böhme Jul 30 '17 at 15:33
  • Christoph: That was it. I removed the jar I had. Replaced it with jboss-remoting-3.2.7ga.jar. And I can see a createEndpoint() with a 2-parameter signature. Grin ... wish I could say yahoo! it worked. But at least it cleared my NoSuchMethodError. Now I can move on the some new xino error. BUT ... first I need to pay the bounty to you. Here's hoping that doesn't turn out harder to figure out than this was. Because this has been a nightmare. Thank you. – George Jul 31 '17 at 01:24
  • Christoph: You need to post you comment up in the item that has the +50 icon in the left column or I can't award it. – George Jul 31 '17 at 01:34
  • Or maybe post ii as a new post not a comment to this posting. But somehow we need to get that little icon next to something you post. – George Jul 31 '17 at 01:51
  • Glad that the problem is solved. I made my comment into a new [answer](https://stackoverflow.com/a/45408123/8362098). Hope this works for awarding the bounty. Regarding your new problem with the XNIO error: I suggest to check the jar versions again. Your version of xnio-api seems to be an older one than the one pulled by my Maven dependency. I added the actual jars on the classpath to my [original answer](https://stackoverflow.com/a/45382416/8362098) as the seem to play a crucial role in this problem. – Christoph Böhme Jul 31 '17 at 05:36
0

Here is your obligatory "that's a dumb question." Does the wildfly remote quickstart github repo answer the question for you? Their code, from RemoteEJB.java

final Hashtable<String, String> jndiProperties = new Hashtable<>();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
return (RemoteCalculator) context.lookup("ejb:/ejb-remote-server-side/CalculatorBean!" + RemoteCalculator.class.getName());
K.Nicholas
  • 10,956
  • 4
  • 46
  • 66
  • Hi Karl: Thanx, but no luck with those properties either. Please see above. I'm pretty sure the current error is NOT related to properties. It is the NoSuchMenthodError above that never lets execution get to the point of tying to contact WF. {Grin ... Not to say that once past the NoSuchMethodError I won't have property problems.) But first I have to get past the NoSuchMentodError, So as I mentioned I'm going to re-post that as a new question.. – George Jul 30 '17 at 23:34
0

According to your own answer the following jars are on your classpath:

  • jboss-remote-naming-1.0.7.final.jar
  • jboss-logging.jar
  • xnio-api-3.0.7.ga.jar
  • jboss-remoting-3.jar
  • jboss-ejb-client-1.0.19.final.jar

You write that the application throws the following exception:

java.lang.NoSuchMethodError: 
org.jboss.remoting3.Remoting.createEndpoint(Ljava/lang/String;Lorg/xnio/OptionMap;)Lorg/jboss/remoting3/Endpoint;]

This exception is thrown when org.jboss.naming.remote.client.EndpointCache which is part of the jboss-remote-naming jar tries to call Remoting.createEndpoint() which is contained in the jboss-remoting jar.

As you explain in your answer the reason for this is that the Remoting class declares a 3-parameter version of the createEndpoint() method while the EndpointCache class tries to call a 2-parameter version which does not exist.

I checked the commit histories and declared dependencies of the jboss-remote-naming and the jboss-remoting projects to find out what is going wrong there. This is what I found out:

The 2-parameter version of createEndpoint() was only added in version 3.2 of jboss-remoting. The pom.xml for jboss-remote-naming-1.0.7.final says it depends on jboss-remoting 3.2.7.GA.

As there is no version number on your jboss-remoting-3.jar, I guess it is an older version. You should be able to check this by looking for a pom.xml in META-INF folder of your jboss-remoting-3.jar. This should contain the version number.

To solve your problem, I suggest to replace your jboss-remoting-3.jar with jboss-remoting-3.2.7ga.jar or to use the set of jars I listed in my other answer.

Christoph Böhme
  • 3,766
  • 1
  • 19
  • 29
  • Hi Chrisoph: Hope that worked. I clicked on the bounty. And I clicked this post as the answer. And yes ... I'm back into a Xnio problem with everything pointing to JARS AGAIN. But I have xnio-api-3.4.6.Final.jar in my build path, and my WF console says "11:54:24,764 INFO [org.xnio] (MSC service thread 1-1) XNIO version 3.4.0.Final". So I'm stuck again. But I should probably post that separately ... grin ... among the others posts that have no other answer yet. Thanks again. – George Jul 31 '17 at 21:59
  • Hi George: Yes, that worked, thank you. Hope you get your other problems solved, too. – Christoph Böhme Aug 01 '17 at 05:04