7 Replies Latest reply: Mar 13, 2013 7:28 AM by EJP RSS

    Caching Remote interface and initialContext causes [EJB:010160]Security

    729470
      Hi everyone,

      I have a swing application that invokes stateless EJBs which deployed on WLS 10.3. The stateless EJB is secured via JAAS. Swing client get remote interface by JNDI lookup.
      To improve performance, I want to cache the initialContext so that the initialContext is created only once at client side. For the same reason I want to cache the remote interface at client side.

      I put the security principle and credential of current user in the initialContext. The first invocation of stateless EJB method succeeded. After that, every remote method invocation results 'javax.ejb.EJBAccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB'.

      I think this is not because of the caching of remote interface since If I creat initialContext before each invocation of stateless EJB method, the exception does not occur.

      Is caching remote interface and initialContext wrong idea? If not, what is the right implementation?

      Any suggestion is welcome.
        • 1. Re: Caching Remote interface and initialContext causes [EJB:010160]Security
          r035198x
          This looks like a code issue where your second invocation is being made using a new context object rather than the one you used successfully before. How are you caching these objects?
          • 2. Re: Caching Remote interface and initialContext causes [EJB:010160]Security
            EJP
            To improve performance, I want to cache the initialContext so that the initialContext is created only once at client side. For the same reason I want to cache the remote interface at client side.
            Do you have any evidence that this would actually improve performance?
            • 3. Re: Caching Remote interface and initialContext causes [EJB:010160]Security
              729470
              I am using a static method to get a singleton initialContext. The code is something like below:

              private static Context context = null;

              +public static getInitialContext(){+
              +if(context ==null){+
              context=createContext();
              +}+
              return context;
              +}+

              +private static Context getInitialContext() throws NamingException {+
              Hashtable env = new Hashtable();
              +// WebLogic Server 10.x connection details+
              env.put(Context.INITIAL_CONTEXT_FACTORY,
              SystemConfigProvider.getProperty(Context.INITIAL_CONTEXT_FACTORY));
              env.put(Context.PROVIDER_URL,
              SystemConfigProvider.getProperty(Context.PROVIDER_URL));
              env.put(Context.SECURITY_PRINCIPAL, "Tester");
              env.put(Context.SECURITY_CREDENTIALS, "Tester");
              return new InitialContext(env);
              +}+
              • 4. Re: Caching Remote interface and initialContext causes [EJB:010160]Security
                729470
                I did some experiments today.

                I found that the singleton initialContext was first created in the login thread other than the main swing application thread.
                The method invocation in the login thread was successful. After that the invocations in main thread throws exception about anonymous user.

                And if I change the code so that the singleton initialContext was first created in the main swing application thread, the exception disappear....

                I am wondering if it is about the initialContext thread safe problem? I cannot figure out why the principle of the context is changed to anonymous.
                • 5. Re: Caching Remote interface and initialContext causes [EJB:010160]Security
                  r035198x
                  Still your error suggests that you passed in a context that does not have a user name set up. Maybe the code you are using to make the invocation has a problem or the problem is elsewhere perhaps even at server side.
                  As to whether this will improve performance or not a common answer is it depends but JNDI lookup is costly and Handles cache was almost a must for EJB 2.1. I would cache as part of ServiceLocator pattern anyway if it's EJB 3 but for 3.1 I would look at some statistics first before putting the caching solution into production.
                  • 6. Re: Caching Remote interface and initialContext causes [EJB:010160]Security
                    996481
                    Hi,
                    I think the reason is the next call is made in different thread!
                    Everytime when create a InitialContext, a subject is associalted with current thread, so if you want to cache the InitialContext and remote interface ,then you should cache the subject too.
                    In my system, we use weblogic specific api to accomplish this:
                    -----
                    when create the context,cache the subject :
                    -----
                    Context context=new InitialContext(param);
                    Subject subject = weblogic.security.Security.getCurrentSubject();
                    -----
                    after that ,use the cached subject to make the call:
                    -----

                    obj = weblogic.security.Security.runAs(
                    subject,
                    new PrivilegedExceptionAction()
                    {
                    public Object run() throws Exception
                    {
                    try {
                    Object o =bizService.call();
                    return o;
                    } catch (InvocationTargetException e)
                    {
                    throw e;
                    }
                    }
                    })

                    Edited by: 993478 on 2013-3-12 下午11:46

                    Edited by: 993478 on 2013-3-12 下午11:46
                    • 7. Re: Caching Remote interface and initialContext causes [EJB:010160]Security
                      EJP
                      JNDI contexts are not thread safe. See the Javadoc.

                      As I hinted above, they are also implemented with a lot more intelligence than you seem to assume. There is nothing to be gained by using singleton Contexts. They already do connection pooling behind the scenes.

                      Just throw it all away.