Well, we got stuck again :(
Here's the dilema:
We need the ProxyServlet to handle requests, so it is loaded from
webappclassloader, so we need the equinox jar in our web-inf/lib
We need the Activator from equinox to get started outside the
webappclassloader, it has to be loaded by context classloader
So we have this:
WEB-INF/
lib/
equinox-servlet.jar
bundles/
equinox-servlet.jar
Now, the problem happens here:
ProxyServlet (from equinox) calls
Activator.addProxyServlet(this)
The method:
static synchronized void addProxyServlet(ProxyServlet proxyServlet) {
ServiceRegistration registration = null;
if (context != null)
registration = registerHttpService(proxyServlet);
serviceRegistrations.put(proxyServlet, registration);
}
Ok, of course the damn context will be null, ProxyServlet was loaded by
webappclassloader whereas the Activator was started by our
contextclassloader
So, no way we get HttpService registred this way.
The other way around:
Having our servlet starting equinox Activator:
Well now we do have an HttpService installed as service but... It comes from
a differente classloader :( and can't be used by our bundles.
I guess we hit a dead end here? Is there a solution for this?
Regards
On Thu, Jan 29, 2009 at 3:25 PM, Richard S. Hall <[email protected]>wrote:
> Vinicius Carvalho wrote:
>
>> Sorry for the mess. Neil, I was just mentioning that you left a post at my
>> twitter a month ago. I read both books, and they are equally great. Some
>> things better in one, others in other. I do recommend everyone to get both
>> of em :)
>>
>>
>
> Don't worry, it's just Neil (he's British). ;-)
>
> -> richard
>
> On Thu, Jan 29, 2009 at 3:01 PM, Richard S. Hall <[email protected]
>> >wrote:
>>
>>
>>
>>> Neil Bartlett wrote:
>>>
>>>
>>>
>>>> Hi Vinicius,
>>>>
>>>> Glad to help, and thanks for your kind comments about my book.
>>>>
>>>> However I think it's the authors of "OSGi in Action" who are asking
>>>> for a book review at the moment, since they have just released some
>>>> chapters for early access. They are on this mailing list so can
>>>> probably clarify. My book is "OSGi in Practice". Yes, these two titles
>>>> are confusingly similar... my defence is that I started writing my
>>>> book first!
>>>>
>>>>
>>>>
>>>>
>>> We aren't asking for a book review, but there was some review recently on
>>> DZone about the early access release from a few weeks back.
>>>
>>> Regarding the titles, we didn't really choose the title per se, but "X in
>>> Action" and even "X in Practice" titles are both Manning Publishing
>>> series
>>> books from what I understand. So you be the judge. ;-)
>>>
>>> -> richard
>>>
>>> Kind regards,
>>>
>>>
>>>> Neil
>>>>
>>>> On Thu, Jan 29, 2009 at 4:45 PM, Vinicius Carvalho
>>>> <[email protected]> wrote:
>>>>
>>>>
>>>>
>>>>
>>>>> Bullseye! Thanks Neil. I've tested and got a ClassCastException ...
>>>>>
>>>>> We'll look into our code and check why is this happening. We've just
>>>>> tried,
>>>>> and in a debug breakpoint we've seen that the service returned by:
>>>>> HttpService httpService = (HttpService)
>>>>> context.getService(reference);
>>>>>
>>>>> Was indeed HttpServiceImpl, I guess we have a classloader problem. We
>>>>> have
>>>>> the equinox servletbridge inside webinf/lib, hence it's loaded by
>>>>> WebApplicationClassLoader. Since this bundle is loaded by
>>>>> ContextClassLoader
>>>>> that might be the problem, we don't know.
>>>>>
>>>>> I'll look into it. Thanks a lot for your help, it gave us hope again :)
>>>>>
>>>>> I owe you a book review (from your message at twitter.com). I've
>>>>> finished
>>>>> you book btw, best chapter is chapter 6 (concurrency is a subject that
>>>>> is
>>>>> not very well explained in most books, which is a shame since it lead
>>>>> to
>>>>> really annoying problems) Promise to write a few lines of revuew to you
>>>>> soon.
>>>>>
>>>>> Regards
>>>>>
>>>>>
>>>>> On Thu, Jan 29, 2009 at 11:57 AM, Neil Bartlett <[email protected]
>>>>>
>>>>>
>>>>>> wrote:
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> It's possible that the HttpService published in the service registry
>>>>>> is not compatible with your bundle that is trying to track it. This
>>>>>> could happen if you have multiple bundles exporting the
>>>>>> org.osgi.service.http package, or if your tracking bundle has somehow
>>>>>> included the org.osgi.service.http package instead of importing it.
>>>>>>
>>>>>> To check if this is the case, try changing the start() method of your
>>>>>> Activator to call httpServiceTracker.open(true) rather than just
>>>>>> httpServiceTracker.open(). This will force the tracker to find all
>>>>>> HttpServices, even the incompatible ones. Of course you will soon get
>>>>>> a ClassCastException when you try to use the returned service, so you
>>>>>> need to fix the underlying problem. Doing this will simply tell you if
>>>>>> that is indeed the problem.
>>>>>>
>>>>>> Regards,
>>>>>> Neil
>>>>>>
>>>>>> On Thu, Jan 29, 2009 at 1:48 PM, Vinicius Carvalho
>>>>>> <[email protected]> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> Hello all, sorry for always comming back on the same subject, but
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> tomorrow
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> is our deadline, and even we got some progress on the osgi front with
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> spring
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> (we now have services and dependency injection working). Nothing
>>>>>>> seems
>>>>>>> to
>>>>>>> work on the HttpService integration.
>>>>>>>
>>>>>>> We tried almost everything to get equinox running inside a servlet
>>>>>>> container. The documentation on equinox servlet bridge is almost
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> inexistent.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> We are not using their servletbridge since it starts the osgi
>>>>>>> container
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> and
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> that is something we are doing in our code (following the sling
>>>>>>> approach)
>>>>>>>
>>>>>>> What seems to be happening is that any service tracker registered to
>>>>>>> HttpService never gets called, ever... We've seen this on the
>>>>>>> OsgiManager
>>>>>>> class, and now we decided to drop our own little servlet bundle:
>>>>>>>
>>>>>>> public class Activator implements BundleActivator {
>>>>>>> private ServiceTracker httpServiceTracker;
>>>>>>>
>>>>>>> public void start(BundleContext context) throws Exception {
>>>>>>> httpServiceTracker = new HttpServiceTracker(context);
>>>>>>> httpServiceTracker.open();
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> public void stop(BundleContext arg0) throws Exception {
>>>>>>> httpServiceTracker.close();
>>>>>>> httpServiceTracker = null;
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> private class HttpServiceTracker extends ServiceTracker {
>>>>>>>
>>>>>>> public HttpServiceTracker(BundleContext context) {
>>>>>>> super(context, HttpService.class.getName(), null);
>>>>>>> }
>>>>>>>
>>>>>>> public Object addingService(ServiceReference reference) {
>>>>>>> HttpService httpService = (HttpService)
>>>>>>> context.getService(reference);
>>>>>>> try {
>>>>>>> httpService.registerServlet("/dummy", new
>>>>>>> DummyServlet(),
>>>>>>> null, null); //$NON-NLS-1$
>>>>>>> } catch (Exception e) {
>>>>>>> e.printStackTrace();
>>>>>>> }
>>>>>>> return httpService;
>>>>>>> }
>>>>>>>
>>>>>>> public void removedService(ServiceReference reference, Object
>>>>>>> service) {
>>>>>>> HttpService httpService = (HttpService) service;
>>>>>>> httpService.unregister("/dummy"); //$NON-NLS-1$
>>>>>>> super.removedService(reference, service);
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> Well, the adding servlet never gets called :(
>>>>>>>
>>>>>>> Here how we start the felix container:
>>>>>>>
>>>>>>> public void init() throws ServletException {
>>>>>>> ServletContextResourceProvider rp = new
>>>>>>> ServletContextResourceProvider(getServletContext());
>>>>>>> Logger logger = new ServletContextLogger(getServletContext());
>>>>>>> Map<Object, Object> props = loadProperties();
>>>>>>> this.osl = new OSL(rp,props,logger);
>>>>>>> this.delegatee = new HttpServiceServlet();
>>>>>>> this.delegatee.init(getServletConfig());
>>>>>>>
>>>>>>> super.init();
>>>>>>> }
>>>>>>>
>>>>>>> public class OSL implements BundleActivator {
>>>>>>>
>>>>>>> private Felix felix;
>>>>>>> private ReadWriteLock felixLock;
>>>>>>> private ResourceProvider resourceProvider;
>>>>>>> private Logger logger;
>>>>>>> private BundleActivator httpServiceActivator;
>>>>>>>
>>>>>>> public OSL(ResourceProvider rp, Map<Object, Object> props, Logger
>>>>>>> logger){
>>>>>>> this.resourceProvider = rp;
>>>>>>> this.logger = logger;
>>>>>>> List<BundleActivator> activators = new
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> ArrayList<BundleActivator>();
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> activators.add(this);
>>>>>>> activators.add(new BootstrapInstaller(logger,rp));
>>>>>>> props.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> activators);
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> Felix tmpFelix = new Felix(props);
>>>>>>> try {
>>>>>>> tmpFelix.start();
>>>>>>> this.felix = tmpFelix;
>>>>>>> } catch (Exception e) {
>>>>>>> e.printStackTrace();
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> public void start(BundleContext context) throws Exception {
>>>>>>> this.httpServiceActivator = new Activator();
>>>>>>> this.httpServiceActivator.start(context);
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> As you can see, we are starting the Httpservice ourselves, we tried
>>>>>>> to
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> not
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> do so and pack it with the other bundles, but the effect is the same
>>>>>>> (do
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> not
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> call the addingservice)
>>>>>>>
>>>>>>> After the complete startup we have these services:
>>>>>>>
>>>>>>> System Bundle (0) provides:
>>>>>>> ---------------------------
>>>>>>> org.osgi.service.startlevel.StartLevel
>>>>>>> org.osgi.service.packageadmin.PackageAdmin
>>>>>>> org.osgi.service.http.HttpService
>>>>>>>
>>>>>>>
>>>>>>> So I guess the HttpService is up and running.
>>>>>>>
>>>>>>> Is there anything else that we could do? Any other point to look at,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> replace
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> class, packaging format, anything please. Tomorrow if we don't
>>>>>>> present
>>>>>>> at
>>>>>>> least one servlet (we needed at least the GWT-RPC working but one
>>>>>>> servlet
>>>>>>> should do it), we may have to drop osgi for good, and that's
>>>>>>> something
>>>>>>> we
>>>>>>> are really not willing to do :(
>>>>>>>
>>>>>>> Regards
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: [email protected]
>>>>>> For additional commands, e-mail: [email protected]
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: [email protected]
>>>> For additional commands, e-mail: [email protected]
>>>>
>>>>
>>>>
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>>
>>>
>>>
>>>
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>