Issue Details (XML | Word | Printable)

Key: JETTY-181
Type: Improvement Improvement
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Jan Bartel
Reporter: Florent BENOIT
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Jetty

ENC environment per thread and not only per classloader

Created: 23/Nov/06 11:39 AM   Updated: 08/Dec/06 01:01 PM
Component/s: J2EE/Extra
Affects Version/s: 6.1.0
Fix Version/s: 6.1.0rc0

Time Tracking:
Original Estimate: 20 minutes
Original Estimate - 20 minutes
Remaining Estimate: 20 minutes
Remaining Estimate - 20 minutes
Time Spent: Not Specified
Remaining Estimate - 20 minutes

File Attachments: 1. Text File jetty.naming.patch (4 kB)

Environment: Jetty SVN version | GNU/Linux | JDK 5


 Description  « Hide
The aims of this improvment is to allow to set a java:comp (ENC) environment to a thread and not to a classloader.
For example, EasyBeans product (EJB3 container) can be packaged in a war file.
Then, when it runs inside Jetty, it has to provide an ENC environment to EJBs. (and to hook up into the existing java: namespace management done by Jetty)

Jetty allows only to set an ENC environment to a classloader. This is done through the org.mortbay.naming.ContextFactory class.

Currently, EasyBeans can be embedded inside Tomcat which allow this kind of settings (ENC per thread) but this is not available inside Jetty.

I agree that it could be considered outside of the scope of the Servlet/JSP specification (as for web application, an ENC should be associated to a classloader), but it will be great if this feature is present in Jetty.

I provide a patch enabling this feature (it uses JDK 5 generics so maybe you have to remove it if you want to ensure it compile with JDK 1.4)
Of course, this can be adapted but this is the basic feature I need to run the EasyBeans product inside Jetty.
The patch allows to set a context to a thread, and when no context is bound to a thread, it works as previously (with classloaders)

Regards,

Florent



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Jan Bartel added a comment - 23/Nov/06 12:14 PM
Many thanks Florent, I'll take a look at this.

Jan Bartel added a comment - 24/Nov/06 01:45 AM
Have you tried this with EasyBeans inside Jetty? If so, where are you callling setComponentContext()?

Florent BENOIT added a comment - 24/Nov/06 02:58 AM
Jan,

Yes I've tried this in EasyBeans but I haven't committed this part as it will depend on the solution provided in Jetty
For now I have the following code:

/**

  • Sets Jetty ENC context.
  • @param invocationContext context with useful attributes on the current
  • invocation.
  • @return result of the next invocation (to chain interceptors).
  • @throws Exception needs for signature of interceptor.
    */
    @Override
    public Object intercept(final EasyBeansInvocationContext invocationContext) throws Exception
    Unknown macro: { // Get the subcontext (comp) Context oldContext = (Context) setComponentContextMethod.invoke(null, invocationContext .getFactory().getJavaContext().lookup("comp")); try { return invocationContext.proceed(); } finally { resetComponentContextMethod.invoke(null, oldContext); } }

Before invoking a business method, the ENC is set on the thread and at the end, the previous context is restored.
And as only comp context can be set (which is OK for me), I bind the comp subcontext extracted from the EJB's factory


Jan Bartel added a comment - 27/Nov/06 05:04 AM
Florent, I've solved this a slightly different way but your patch was the starting point for making me think about this, so thank you! The change I've made is to first try the classloader associated with the current webapp context,and falling back to the thread context classloader if there is no current webapp context. There will always be a current webapp context when we are processing a request. When we aren't processing a request, ie we are setting up the ENC, the thread context classloader will be that of the webapp.

I've checked my change into svn trunk. Can you look at it and try it with EasyBeans and see if it works? I'm hoping you won't need the intercept code and JNDi lookups should just work for you.

FYI, the relevant change I made looks like:

org.mortbay.naming.ContextFactory:

public Object getObjectInstance (Object obj, Name name, Context nameCtx, Hashtable env) throws Exception
{
// First, see if we are in a webapp context, if we are, use
// the classloader of the webapp to find the right jndi comp context
ClassLoader loader = null;
if (ContextHandler.getCurrentContext() != null)

{ loader = ContextHandler.getCurrentContext().getContextHandler().getClassLoader(); }

if (loader != null)

{ if (Log.isDebugEnabled()) Log.debug("Using classloader of current org.mortbay.jetty.handler.ContextHandler"); }

else

{ //Not already in a webapp context, in that case, we must use the //curren't thread's classloader instead loader = Thread.currentThread().getContextClassLoader(); if (Log.isDebugEnabled()) Log.debug("Using thread context classloader"); }

//Get the context matching the classloader
Context ctx = (Context)_contextMap.get(loader);

....
}

cheers
Jan


Jan Bartel added a comment - 27/Nov/06 05:28 AM
While I'm thinking about it, is there anything else we can do to make integration easier? For example, I'm thinking there might be something we should do regarding security (short of implementing JACC) ?

regards
Jan


Florent BENOIT added a comment - 27/Nov/06 06:21 AM
Hi Jan,

EasyBeans is packaged as a war file (with a context listener that starts the embedded container)
So I think it will have a web context associated and it will never use the Thread Context.

I will try but I'm not sure that it will work. This is why I was looking up first the thread context.
This is also the order used in JOnAS application server.

Concerning security/JACC, EasyBeans has a small JACC provider so yes I think we should provide a realm which can use a JACC provider.

Regards,

Florent.


Florent BENOIT added a comment - 27/Nov/06 06:35 AM
Jan,

Here is a follow-up on the new mechanism (using Thread Context classloader)

Different beans of an ejb-jar can have the same classloader.
And each bean has a different ENC environment. (which is different of web-app. 1 war = 1 CL = 1 ENC)

So, by using the context classloader, I will have a problem because it won't be thread safe.
Bean A may use the ENC of the Bean B as they share the same context classloader.

Florent.


Jan Bartel added a comment - 27/Nov/06 10:27 AM
Darn! You're perfectly right. I've been in servlet land so long I forgot all about those ejb ENCs!

So, it looks like your solution is the way to go with a method allowing you to inject your own context. Do you create your own context with your own context impl or do you use Jetty's? If you use your own context, then it's probably best for me to just let you inject it. Otherwise, I could change Jetty so that it doesn't depend on a classloader as the "key" to lookup an ENC - I could change it so it would be possible to use any Object as "key" to attach an ENC to. In the case of webapps, the "key" would be a WebAppContext, and for EJBs it could be ... (guessing here) an EZBContext.

cheers
Jan


Florent BENOIT added a comment - 27/Nov/06 10:41 AM
> Do you create your own context with your own context impl or do you use Jetty's?
I create my own context with my own context impl so I only need jetty to manage my context previously built.
The context is created before and it's the interceptor (JOnAS, EZB standalone, Tomcat, Jetty, etc) which plug the context into the system where EasyBeans is embedded.

As long as I can set my context in a given way (delegating factory, setters, whatever), it should be OK for me.
So I will use what you will provide

Regards,

Florent


Jan Bartel added a comment - 27/Nov/06 12:47 PM
Florent, I've checked in your patch to trunk. Can you test it? Let me know how it goes, I'm excited to get Jetty working with EasyBeans!

cheers
Jan


Florent BENOIT added a comment - 28/Nov/06 09:01 AM
Jan, I've compiled and tested the SVN trunk which include this patch and it seems to work fine.
I've committed in EasyBeans the change to support Jetty (this is linked to this issue: http://jira.easybeans.org/browse/EZB-135)

I will also provide a Jetty package with a Getting started guide.

So next milestone version of EasyBeans should work with next 6.1.0preXX version.

Regards,

Florent.