让OSGi支持JSF Web开发

Posted on 2007-10-08 15:05 罗明 阅读(846) 评论(25)  编辑  收藏 所属分类: JavaOSGiJSF
1. 按照以下代码改写你自己的Activator (或者将代码中的"/pages"改成你的jsf网页路径):
注意加粗的那段代码(使用当前的class loader来加载jsf的FacesServlet)

package net.andyluo.singlife.jsf.demo;

import java.io.IOException;
import java.util.Dictionary;
import java.util.Hashtable;

import javax.faces.webapp.FacesServlet;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.eclipse.equinox.http.helper.BundleEntryHttpContext;
import org.eclipse.equinox.http.helper.ContextPathServletAdaptor;
import org.eclipse.equinox.jsp.jasper.JspServlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.util.tracker.ServiceTracker;

import com.sun.faces.config.ConfigureListener;

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 context) throws Exception 
    
{
        httpServiceTracker.close();
    }


    
private class HttpServiceTracker extends ServiceTracker 
    
{

        
private static final String PATH = "/jsf";

        
public HttpServiceTracker(BundleContext context) 
        
{
            
super(context, HttpService.class.getName(), null);
        }


        
public Object addingService(ServiceReference reference) 
        
{
            
final HttpService httpService = (HttpService) context
                    .getService(reference);
            
try 
            
{
                HttpContext commonContext 
= new BundleEntryHttpContext(context
                        .getBundle(), 
"/pages");
                httpService.registerResources(PATH, 
"/", commonContext);

                JspServlet jspServlet 
= new JspServlet(context.getBundle(),
                        
"/pages");
                Servlet adaptedJspServlet 
= new ContextPathServletAdaptor(
                        jspServlet, PATH);
                httpService.registerServlet(PATH 
+ "/*.jsp", adaptedJspServlet,
                        
null, commonContext);

                Dictionary initparams 
= new Hashtable();
                initparams.put(
"servlet-name""Faces Servlet");
                Servlet adaptedFacesServlet 
= new ServletContextListenerServletAdaptor(
                        
new ConfigureListener(), new
 FacesServlet(), jspServlet
                                .getJspLoader());

                adaptedFacesServlet 
= new ContextPathServletAdaptor(
                        adaptedFacesServlet, PATH);
                httpService.registerServlet(PATH 
+ "/*.jsf",
                        adaptedFacesServlet, initparams, commonContext);

            }
 catch (Exception e) 
            
{
                e.printStackTrace();
            }

            
return httpService;
        }


        
public void removedService(ServiceReference reference, Object service) 
        
{
            
final HttpService httpService = (HttpService) service;
            httpService.unregister(PATH); 
//$NON-NLS-1$
            httpService.unregister(PATH + "/*.jsp"); //$NON-NLS-1$
            httpService.unregister(PATH + "/*.jsf"); //$NON-NLS-1$            
            super.removedService(reference, service);
        }

    }


    
public class ServletContextListenerServletAdaptor implements Servlet 
    
{
        
private ServletConfig config;

        
private ServletContextListener listener;

        
private Servlet delegate;

        
private ClassLoader jspLoader;

        
public ServletContextListenerServletAdaptor(
                ServletContextListener listener, Servlet delegate,
                ClassLoader jspLoader) 
        
{
            
this.listener = listener;
            
this.delegate = delegate;
            
this.jspLoader = jspLoader;
        }


        
public void init(ServletConfig config) throws ServletException 
        
{
            
this.config = config;
            ClassLoader original 
= Thread.currentThread()
                    .getContextClassLoader();
            
try 
            
{
                Thread.currentThread().setContextClassLoader(jspLoader);
                listener.contextInitialized(
new ServletContextEvent(config
                        .getServletContext()));
                delegate.init(config);
            }
 finally 
            
{
                Thread.currentThread().setContextClassLoader(original);
            }

        }


        
public void service(ServletRequest req, ServletResponse resp)
                
throws ServletException, IOException 
        
{
            ClassLoader original 
= Thread.currentThread()
                    .getContextClassLoader();
            
try 
            
{
                Thread.currentThread().setContextClassLoader(jspLoader);
                delegate.service(req, resp);
            }
 finally 
            
{
                Thread.currentThread().setContextClassLoader(original);
            }

        }


        
public void destroy() 
        
{
            ClassLoader original 
= Thread.currentThread()
                    .getContextClassLoader();
            
try 
            
{
                Thread.currentThread().setContextClassLoader(jspLoader);
                delegate.destroy();
                listener.contextDestroyed(
new ServletContextEvent(config
                        .getServletContext()));
                config 
= null;
            }
 finally 
            
{
                Thread.currentThread().setContextClassLoader(original);
            }

        }


        
public ServletConfig getServletConfig() 
        
{
            
return config;
        }


        
public String getServletInfo() 
        
{
            
return "";
        }

    }


}


2. 因为JspServlet中没有返回class loader的方法,所以我们要更改一下JspServlet的实现代码(hack一下):更改equinox的org.eclipse.equinox.jsp.jasper_*.jar中的org.eclipse.equinox.jsp.jasper.JspServlet类:(可以下载JspServlet的源代码,在本地更改编译成功后将class文件覆盖到org.eclipse.equinox.jsp.jasper_*.jar中)

添加以下方法:
    public ClassLoader getJspLoader()
    {
        return this.jspLoader;
    }

如此即可^_^, 其实就是让FacesServlet使用JspServlet的ClassLoader,这样就不会出现"Can't find FacesContext"错误了。

参考: [news.eclipse.technology.equinox] JSF, Equinox & FactoryFinder



版权所有 罗明

Feedback

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-24 01:30 by Yu Liu
请问,我就是按照您这个帖子所说的做的,为什么jsf的组件没有显示出来呢,问题有可能在哪里呢? 我没有用facese config的配置,问题应该不是这里吧

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-24 09:25 by 罗明
你加上faces-config.xml再试试,应该要这个配置文件的

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-24 18:01 by Yu Liu
谢谢答复! 请问你手头有没有可以运行的jsf和osgi的小例子,有能够发给我一份吗? 这是我的信箱 dogwood.liu@gmail.com

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-24 21:01 by Yu Liu
我定义了配置文件,页面能被osgi正确找到,可是组建还是显示不出来,就是一个空白的页,非jsf的组建能够显示出来,jsf的不行。另外配置文件应该放在哪个目录呢,我房子和jsf文件的同一个目录没用啊

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-24 22:43 by 罗明
把demo发给你了,你看看里面的目录结构

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-25 09:33 by Yu Liu
谢谢啊! 我看了你那个demo的文件结构了,好像不能够直接运行。我自己按照你那样的目录结构弄了一个,但是运行的时候找不到 faceservlet 或者 configlistener. 很是奇怪,我编译的时候没事,但是运行的时候不行,我已经把我自己弄得那个plugin发给你了,不知道你有没有时间看看,我哪里配置的不对

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-25 11:30 by Yu Liu
请问你用不用 qq msn 或者 googletalk 什么的,有些问题想在线请教一下

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-01-25 15:04 by 罗明
都用,页面上有三个的联系方式

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-03-03 10:43 by lmr
能否发给我一份
lialiks@163.com
谢谢

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-25 18:20 by gembin
给我发1份Demo,急需阿,十分感谢!!gembin@gmail.com
请问如何让JBoss的Ajax4JSF,RichFaces运行在OSGi 环境下

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:44 by 传奇世界私服
4968

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:44 by 传世私服
6125

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:44 by 魔兽世界私服
1315

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:44 by 魔兽世界私服
9608

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:47 by 魔兽世界私服
7313

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:47 by 魔兽世界私服
7655

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:48 by 魔兽世界私服
3423

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:48 by 魔兽世界私服
6475

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:48 by 魔兽世界私服
7937

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:48 by 魔兽世界私服
0480

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:48 by 魔兽世界私服
9379

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:48 by 魔兽世界私服
2937

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:49 by 魔兽世界私服
0665

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:49 by 魔兽世界私服
3271

# re: 让OSGi支持JSF Web开发  回复  更多评论   

2008-05-31 10:49 by 魔兽世界私服
1268

标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-11-15 00:01 编辑过