1 2 Previous Next 15 Replies Latest reply on Sep 28, 2008 4:55 AM by Christian Schuhegger

    Component Proposal - Configurable Service Locator

    Andrew Rubinger Master

      Given the number of JNDI/InitialContext-related questions concerning client access to EJB3 Services on the User Forum, I'd like to suggest JBoss provide a a configurable Service Locator included w/ EJB3. Depending on feedback here, I'll gladly assume development responsibility.


      *Bring ease-of-use to the EJB client what the 3.0 Spec did for server components

      * Minimized coupling between configuration and code; avoid the need for hardcoding service names or JNDI locations

      * Lookup by business interface (eg. ServiceLocator.getInstance().getService(MyBusinessInterfaceRemote.class);)

      * Caching of proxy stubs for SLSB, @Service; Factories and Connections for Queue, Topic (minimize JNDI calls)

      * Field-level injection of proxy stubs into arbitrary client code

      * Support N JNP Hosts in configuration; make location of services transparent to programmer

      I've employed a good number of the objectives above and have enjoyed the results. Looking for confirmation that this will be worth pursuing, and location in which to make commits (Branch 4.0 or TRUNK in SVN I'd assume).


        • 1. Re: Component Proposal - Configurable Service Locator
          Scott Stark Master

          Its should be done in trunk as part of the client deployer/container refactoring work Carlo is doing. You need to tie these points into specifics of the client deployer/container behavior.

          • 2. Re: Component Proposal - Configurable Service Locator
            Andrew Rubinger Master

            Thank you, Scott.

            Will need to read further on the JEE 5 Spec (Chapter 9, specifically) and determine how I might best assist Carlo. If anyone has a couple tasks they'd like to offload in this area, I'm open and available.


            • 3. Re: Component Proposal - Configurable Service Locator
              Carlo de Wolf Master

              Please take a look at: http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/injection/

              I'm rewriting the injection framework there.

              Note that the JavaEE 5 client specifications already solve most of the problems you describe. With the new clients you can do:

              @EJB MySession session;
              to get a reference without JNDI calls. I don't know about the caching part. It's easier to have every injection do a JNDI call, then try to differentiate which calls won't create a new object and which calls do. The usual client application will most likely cache SLSB references anyway.

              A public ServiceLocater might be nice to get references to EJB's based on interface.

              With the last item you mean: having the client use services located on difference hosts? That would be cool. It's in violation with JavaEE 5 spec though so we need to clearly separate it from a regular JavaEE 5 client.

              • 4. Re: Component Proposal - Configurable Service Locator
                Andrew Rubinger Master

                Thanks for your input, Carlo.

                I've reviewed the relevant parts of the JEE5 Spec (Injection and Client Chapters) and am in the process of putting together my own Application Client to run against JBoss built from TRUNK.

                Yes, a lot of the issues I'd addressed are handled in the spec. Not covered, and handled by a potential ServiceLocator:

                * Lookup by interface

                * Lookup AFTER the main method is called (the spec dictates that injection is done once, via static members, before "main" on the client. What about after?)

                * @Service injection? How is this currently being handled as a JMX Service Bean is a JBoss-specific extension?

                And yes, I'd really like to have a client access services on more than one host. This may be outside the discussion of the client container; take into account the case of an EJB with dependencies on other remote EJBs:

                * Client contacts Application Services as JEE5 Application Client
                * Application Services depend on some set of Core Services used by many applications - contact via ServiceLocator

                The core services may be hosted at any number of locations.

                I'd like to determine how to best address this issue if possible.


                • 5. Re: Component Proposal - Configurable Service Locator
                  Bill Burke Master

                  Maybe we should allow a pluggable default strategy for determining JNDI bindings? This would be plugged into the server side and would specify how the EJB container should bind to JNDI.

                  • 6. Re: Component Proposal - Configurable Service Locator
                    Emmanuel Bernard Master

                    Seam provide a JNDI binding strategy using an el

                    • 7. Re: Component Proposal - Configurable Service Locator
                      J-C jc Apprentice

                      Sorry if it is not the right place for my comments.

                      My client application uses Spring framework as ServiceLocator. Injection is done using spring configuration files instead of annotations.

                      From my point of view one of the most important features of the ServiceLocator is to make client application source code independant of the technology used. With my "Spring" solution, client only see interfaces for the service. It does not have to know if the service is an EJB3, RMI, ... It is quite important for me in order to be able to reuse existing services (some of them are distibuted with RMI, others as EJB3 services and some of them with a custom distribution based on Corba).

                      Another requirements for a ServiceLocator is to be able to add at runtime some interceptors. For example, during the debug, I change the interceptor to provides some specific features such as chech that remote service are not invoked in Swing EventispatcherThread, measure time required to perform a service, ... With Spring I have been able to do that (for stateless services only) using a MBean that force Spring framework to reload XML service description file.

                      JNDI parameters are in XMLs, they can be changed easily.
                      Moving services from one EAR to another does not have impact on client source code but only on XMLs.

                      Injection is performed on method not on field.

                      From your point of view is what I am doing wrong or is it just another way to do the same things ?

                      • 8. Re: Component Proposal - Configurable Service Locator
                        Bill Burke Master


                        From your point of view is what I am doing wrong or is it just another way to do the same things ?

                        IMO, there is rarely a right/wrong way just better ways. For client configuration your way is better. The Java EE Client container can provide the same funtionality for you though in most cases (minus interceptors and XML reloading). The JBoss equivalent to Spring container is JBoss Microcontainer i fyou want to try that out.

                        JNDI parameters are in XMLs, they can be changed easily.
                        Moving services from one EAR to another does not have impact on client source code but only on XMLs.

                        Don't bash annotations. Using annotations are great for fast prototyping or generally providing default values for your injections. What I'm saying is that even if you use annotations, you can still override them in XML (web.xml, ejb-jar.xml, etc...) to provide the JNDI mappings you desire. The specifications also support partial XML deployment descriptors so it is real easy to override one env/ entry.

                        • 9. Re: Component Proposal - Configurable Service Locator
                          Andrew Rubinger Master

                          This weekend I've finally been able to dedicate some time to addressing the issues I'd outlined above. The result is a project including a:

                          * Public Service Locator
                          * SLSB and SFSB Test EJBs
                          * Test Client invoking EJBs using Service Locator

                          The ServiceLocator is currently configured using a file "META-INF/service-locator.xml", which is responsible for declaring 1 or more JNP Hosts, and then mapping a series of Services (JNDI Addresses) to them.

                          Once packaged, the Client easily calls invocations:


                          ...illustrated above as a lookup by interface.

                          All non-SFSB Services are cached internally by the ServiceLocator such that subsequent requests will not require a trip to JNDI for the stub.

                          My next steps:

                          * Integrating with JBoss if approved by EJB3 Spec Leads (Bill, Carlo)?
                          * Tying into Carlo's Injection Framework to allow field-level injection in addition to static ServiceLocator lookup calls
                          * Creating a Deployer (or enhancing a current one, EjbDeployer?) to scan for an annotation demarcating which classes contain potential ServiceLocator injections

                          Should I be placing this project in an SVN Repository I create? As a new project (maybe in JBoss Labs)? I do have committer access but would like someone more familiar with proper policies to let me know where the code would be most welcome.

                          Some direction, especially from Carlo in regards to getting Injection integrated, would be most appreciated.

                          I believe this work will greatly simplify the task of creating Distributed Applications in EJB3.


                          • 10. Re: Component Proposal - Configurable Service Locator
                            Carlo de Wolf Master

                            You can commit it in https://svn.jboss.org/repos/jbossas/projects/ejb3/trunk/locator.
                            Try to make the directory simular to other JBoss projects and if possible add a maven2 pom for compilation. You can look at projects/javaee for examples (the ones in ejb3 are outdated). You'll probably need the JavaEE API anyway (as soon as I have the new maven-deploy-plugin working they will appear in the repository).

                            • 11. Re: Component Proposal - Configurable Service Locator
                              Andrew Rubinger Master

                              Will take care of this as soon as I get a chance to Mavenize - thank you.


                              • 12. Re: Component Proposal - Configurable Service Locator
                                Andrew Rubinger Master

                                Going to bring this one back and continue development looking forward.

                                I'm looking to limit the scope (for this first phase) of this component to the following points, which I find lacking in the JEE5 Spec for Application Clients. Eventually I'd like to work this into the Client Container/Deployer as a JBoss extension to the spec - I'm not looking to compete, but enhance.

                                * Support N Remote Hosts

                                * Provide programmatic access to remote services/beans (non-injected)

                                * Allow lookup outside of "main" class

                                EE9.4, Second Paragraph:
                                Injection is also supported for the application client main class.

                                * Allow runtime lookup

                                EE9.4, Second Paragraph:
                                Injection occurs before the main method is called.

                                * Provide caching facility for non-SFSB

                                * Dont restrict to "java:" namespace

                                EE9.4, First Paragraph:
                                Application clients use the java: JNDI namespace to access these items.

                                The moving parts I'm proposing and will be working on:

                                Client-side Library

                                Will be charged with:

                                * Performing lookups
                                * Caching
                                * Requesting of the configured hosts which services are available

                                This is currently being re-written from a working implementation I've been using for the past year or so, and is housed in "projects/ejb3/trunk/locator". There is no formal build or POM as it stands, but I'll be adding these shortly when things are more stable and the refactoring has progressed.


                                I believe this speaks to Bill's points about determining JNDI bindings, but also addresses a cross-reference to the business interfaces implemented by the EJB. Will be implemented as a POJO and deployed in ejb3-deployers-beans.xml; also to be exposed as an MBean for outside access.


                                On successful deployment of an EJB3 Deployable Unit (in "deploy" of EJBStage2Deployer?) , register with the new EJB3Registrar the EJBContainer and draw relationships between the implemented business interfaces and the resultant JNDI Addresses. Haven't fleshed this out yet.


                                • 13. Re: Component Proposal - Configurable Service Locator
                                  Bill Burke Master

                                  Can you post some small examples? I'm trying to understand why we need this.

                                  • 14. Re: Component Proposal - Configurable Service Locator
                                    Andrew Rubinger Master

                                    "Need" is pretty subjective, I suppose.

                                    I'm trying to alleviate the confusion prevalent on the user's forums regarding "where is my EJB?" and "why can't I cast this properly?" by abstracting the JNDI calls from EJB clients.

                                    In short, I think making an enterprise client should be as simple as configuring a number of remote application server(s), and requesting services of them.


                                    Compared to:

                                    Properties props = [configuration];
                                    Context ctx = new InitialContext(props);
                                    MyServiceRemote myService = null;
                                    Object obj = ctx.lookup([some JNDI address that could be transparent to the developer]);
                                    myService = (MyServiceRemote)PortableRemoteObject.narrow(obj,MyServiceRemote.class);

                                    ...which at first glance really only looks like a few lines of code, but really:

                                    * The client has to know ahead of time the JNDI Address of the remote service. What if this changes on the app server? I can imagine more than a few cases of repackaging/changing EAR names across different versions, and then the client code/configs would have to be updated as well.

                                    * SLSB and JMX stubs should be cached to avoid the overhead of JNDI trips; why not make a lib that'll do this for the developer rather than imposing this responsibility on the community?

                                    The "need" comes into play the second an application developer wants to do any of the things not addressed by JEE Application Clients (above post). There are plenty of cases in my current application where I'm not running a main class, or I'd like to invoke a Service from a non-EJB component (where injection isn't available even in-container).


                                    1 2 Previous Next