Search code examples
servletsjbossclassloaderequinoxbridge

how to load class from jar inside equinox server side application in jboss 7


I'm face a problem since few days and I can't get solution. below is my app structure:

I have ejbapp.jar inside MyearDeployedOnJboss7.ear at the same level of equinox-server-side-app.war (built using warproduct) and I want to load class from MyJarToLaoadForEjbapp.jar which is in iModernizeWebClient_1.0.0.jar which is in plugins folder of equinox-server-side-app.war (I want show image of app structure but I cannot send image because forum rules need 10 score to be able to do that)

My question is how to allow ejbapp.jar load classes from "MyJarToLaoadForEjbapp.jar" inside MyWebClient_1.0.0.jar's plugin folder which is in the equinox-server-side-app.war.

I think using servletbridge classloader but no idea how to use it.

in my launch.ini I've:

osgi.*=@null org.osgi.*=@null eclipse.*=@null osgi.parentClassloader=app osgi.contextClassLoaderParent=app

Solution

  • I resolved my proble using Servlet HttpServiceTracker from the OSGI spec. how to do it : write HttpServiceTracker liket that :

    public class HttpServiceTracker extends ServiceTracker {
    
    private static final Logger logger = Logger
            .getLogger(HttpServiceTracker.class.getName());
    
    
    public HttpServiceTracker(BundleContext context) {
        super(context, HttpService.class.getName(), null);
    }
    
    public Object addingService(ServiceReference reference) {
        HttpService httpService = (HttpService) context.getService(reference);
        logger.info("default context path : "
                + org.eclipse.rap.ui.internal.servlet.HttpServiceTracker.ID_HTTP_CONTEXT);
        try {
            logger.info("will register servlet ");
            httpService.registerServlet("/programLauncherServlet",
                    new ProgramLauncherServlet(), null, null);
            logger.info("servlet has been registred with http context ");
            // httpService.registerResources( "/", "/html", null );
        } catch (Exception e) {
            //e.printStackTrace();
            logger.info("The alias '/programLauncherServlet' is already in use");
        }
    
        return httpService;
    }
    
    public void removedService(ServiceReference reference, Object service) {
        logger.info("will unregister servlet ");
        HttpService httpService = (HttpService) service;
        httpService.unregister("/programLauncher");
        super.removedService(reference, service);
        logger.info("servlet has been unregistred");
    }
    

    in your plugin activator class at method start :

    @Override
    public void start(BundleContext context) throws Exception {
        super.start(context);
        Activator.plugin = this;
    
        BundleContext osgiContext = BundleReference.class
                .cast(AnyClassOfYourProject.class.getClassLoader()).getBundle()
                .getBundleContext();
        serviceTracker = new HttpServiceTracker(osgiContext);
        serviceTracker.open();
        LOGGER.info("servlet published !!");
        LOGGER.info("Bundle started.");
    }
    

    and for unregister the servlet at the stop method :

    public void stop(BundleContext context) throws Exception {
        Activator.plugin = null;
        serviceTracker.close();
        serviceTracker = null;
        LOGGER.info("servlet unregistered from context !!");
        super.stop(context);
    }
    

    that's all. your servlet is accessible outside your eclipse bundle and you can call methods inside the bundle.