<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 1  文章 - 37  trackbacks - 0
    <2009年9月>
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    留言簿(16)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    test

    搜索

    •  

    最新評(píng)論

    關(guān)于本文
    本文是之前寫的Developing Equinox/Spring-osgi/Spring Framework Web Application系列的升級(jí)版,Tomcat-OSGi的基礎(chǔ)Demo之一,主要演示傳統(tǒng)web application到OSGi application的轉(zhuǎn)換,由于是升級(jí)版,所以本文的側(cè)重點(diǎn)不再是基礎(chǔ)配置的演示。

    一、準(zhǔn)備工作

    1,JDK 1.6
    2,Eclipse 3.4-jee
    3,Spring-framework-2.5.6
    4,spring-osgi-1.2.0
    5,   org.eclipse.equinox源碼,可從 :pserver:anonymous@dev.eclipse.org:/cvsroot/rt  中獲得

    二、顯示首頁(yè)中的幾個(gè)問(wèn)題

    1.  ClassNotFoundException: org.springframework.web.servlet.view.InternalResourceViewResolver

    META-INF/dispatcher/petstore-servlet.xml中定義的bean:
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            
    <property name="prefix" value="/web/jsp/spring/"/>
            
    <property name="suffix" value=".jsp"/>
        
    </bean>

    在之前的版本中,這里是沒有問(wèn)題的,可是在spring-osgi-1.2.0中,卻會(huì)有這個(gè)問(wèn)題,這是因?yàn)槿鄙僖粋€(gè)
    DynamicImport-Package: *

    為何要使用動(dòng)態(tài)引入?
    因?yàn)闊o(wú)法在spring-beans中import定義的bean,因此如果不使用動(dòng)態(tài)引入,那么spring-beans就無(wú)法load定義的bean,而下面統(tǒng)一使用spring-core中的ClassUtils.forName來(lái)查找bean class,是一個(gè)非常好的做法。

    spring-beans中是這樣load一個(gè)bean的
    Class resolvedClass = ClassUtils.forName("org.springframework.web.servlet.view.InternalResourceViewResolver", loader);

    Thread.currentThread().getContextClassLoader()中的ClassLoader是org.eclipse.core.runtime.internal.adaptor.ContextFinder,它是osgi framework的classloader,它通過(guò)查找類調(diào)用堆中距離本次loadClass調(diào)用最近的DefaultClassLoader(bundle的classloader)去加載一個(gè)類。
    DefaultClassLoader中封裝了ClassLoaderDelegate(BundleLoader)查找類的過(guò)程

    spring-beans加載bean class的過(guò)程:
    讀取配置文件 -> 發(fā)現(xiàn)一個(gè)bean配置 -> 通過(guò)ClassUtils加載 -> 使用Thread.currentThread().getContextClassLoader()加載bean class
    ContextFinder加載bean class的過(guò)程:
    從類調(diào)用堆中找到距離最近DefaultClassLoader,使用ClassUtils的DefaultClassLoader來(lái)加載bean class -> 使用ClassUtils所在bundle的BundleLoader去查找一個(gè)類
    BundleLoader加載bean class的過(guò)程在OSGi規(guī)范中有比較詳細(xì)的介紹,這里主要看一下動(dòng)態(tài)引入
    private PackageSource findDynamicSource(String pkgName) {
            
    if (isDynamicallyImported(pkgName)) {
                ExportPackageDescription exportPackage 
    = bundle.getFramework().getAdaptor().getState().linkDynamicImport(proxy.getBundleDescription(), pkgName);
                
    if (exportPackage != null{
                    PackageSource source 
    = createExportPackageSource(exportPackage, null);
                    
    synchronized (this{
                        
    if (importedSources == null)
                            importedSources 
    = new KeyedHashSet(false);
                    }

                    
    synchronized (importedSources) {
                        importedSources.add(source);
                    }

                    
    return source;
                }

            }

            
    return null;
        }


    現(xiàn)在,spring-bean是如何加載一個(gè)bean的過(guò)程就變得非常明了了,ClassUtils在spring-core中,當(dāng)使用spring-core的BundleLoader去加載一個(gè)bean class時(shí),如果沒有動(dòng)態(tài)引入,則會(huì)出現(xiàn)找不到class的情況。
    很明顯,spring-osgi-1.2.0中的spring-core并沒有配置動(dòng)態(tài)引入,在這個(gè)版本中或許是通過(guò)操作classloader來(lái)實(shí)現(xiàn)bean的加載,這個(gè)沒有研究。

    同理,對(duì)于數(shù)據(jù)庫(kù)驅(qū)動(dòng)找不到的問(wèn)題,也可以這樣來(lái)解決。


    2. 找不到tld

    index.jsp中包含了2個(gè)標(biāo)簽庫(kù),在上一個(gè)版本中,將其放入/web/WEB-INF目錄中就可以正常顯示,可是在新版本中卻不行。

    當(dāng)一個(gè)對(duì)jsp的請(qǐng)求到達(dá)時(shí),先將jsp生稱java文件,之后進(jìn)行編譯。而生稱java文件時(shí),需要處理tld資源。
    tld資源路徑的處理是由TldLocationsCache來(lái)完成的,當(dāng)它第一次初始化時(shí),會(huì)在 "/WEB-INF/",classpath中的jar包,web.xml中查找tld文件并緩存起來(lái)。
    private void init() throws JasperException {
            
    if (initialized) return;
            
    try {
                processWebDotXml();
                scanJars();
                processTldsInFileSystem(
    "/WEB-INF/");
                initialized 
    = true;
            }
     catch (Exception ex) {
                
    throw new JasperException(Localizer.getMessage(
                        
    "jsp.error.internal.tldinit", ex.getMessage()));
            }

        }

    這里主要看一下為什么這個(gè)版本中直接將tld文件放入/web/WEB-INF目錄中會(huì)提示找不到tld

    processWebDotXml()方法是處理web.xml的
    scanJars()是處理classpath資源
    processTldsInFileSystem("/WEB-INF/"); 是查找web-inf目錄中的tld (這個(gè)方法在equinox部分的實(shí)現(xiàn)上行不通)

    在方法processTldsInFileSystem("/WEB-INF/")中使用的是當(dāng)前Servlet的ServletContext.getResourcePaths()方法來(lái)獲取web-inf目錄中的tld資源,注冊(cè)equinox-JspServlet的過(guò)程中,做了2層封裝,ServletRegistration和org.eclipse.equinox.jsp.jasper.JspServlet,分別生成了2個(gè)ServletConfig和ServletContext,大概過(guò)程如下:

    ProxyServlet:
    //Effective registration of the servlet as defined HttpService#registerServlet()  
        synchronized void registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext context, Bundle bundle) throws ServletException, NamespaceException {
            checkAlias(alias);
            
    if (servlet == null)
                
    throw new IllegalArgumentException("Servlet cannot be null"); //$NON-NLS-1$

            ServletRegistration registration 
    = new ServletRegistration(servlet, proxyContext, context, bundle, servlets);
            registration.checkServletRegistration();

            ServletContext wrappedServletContext 
    = new ServletContextAdaptor(proxyContext, getServletContext(), context, AccessController.getContext());
            ServletConfig servletConfig 
    = new ServletConfigImpl(servlet, initparams, wrappedServletContext);

            registration.init(servletConfig);
            registrations.put(alias, registration);
        }

    equinox-JspServlet:
    public void init(ServletConfig config) throws ServletException {
            ClassLoader original 
    = Thread.currentThread().getContextClassLoader();
            
    try {
                Thread.currentThread().setContextClassLoader(jspLoader);
                jspServlet.init(
    new ServletConfigAdaptor(config));
            }
     finally {
                Thread.currentThread().setContextClassLoader(original);
            }

        }

    那么processTldsInFileSystem("/WEB-INF/")方法中的ServletContext就是從equinox-JspServlet$ServletContextAdaptor開始的
    public Set getResourcePaths(String name) {
                Set result 
    = delegate.getResourcePaths(name);
                Enumeration e 
    = bundle.findEntries(bundleResourcePath + name, nullfalse);
                
    if (e != null{
                    
    if (result == null)
                        result 
    = new HashSet();
                    
    while (e.hasMoreElements()) {
                        URL entryURL 
    = (URL) e.nextElement();
                        result.add(entryURL.getFile().substring(bundleResourcePath.length()));
                    }

                }

                
    return result;
            }

    代碼中的bundleResourcePath,就是注冊(cè)這個(gè)Servlet填寫的alias——/web/jsp

    現(xiàn)在,已經(jīng)了解如何查找tld了,只要將/WEB-INF目錄放入/web/jsp中就可以了或者注冊(cè)servlet的時(shí)候這樣寫:
    httpService.registerResources("/""/web"null);
    httpService.registerServlet(
    "/*.jsp"new JspServlet(context .getBundle(), "/web"), nullnull);

    為何上一個(gè)版本可以呢?時(shí)間距離太遠(yuǎn),也不太好找源碼,所以沒有研究這部份,我猜測(cè)應(yīng)該是在scanJars()方法中,通過(guò)classloader的URLs遍歷來(lái)獲取的,

    equinox在處理相同HttpContext的ServletContext時(shí),只是將attributes共享,而并沒有共享資源訪問(wèn),在這個(gè)例子中,應(yīng)該是將相同HttpContext中的資源遍歷,在Tomcat-OSGi中,使用的是naming.DirContext去處理資源的查找。

    3. SpringMVC中的Controller 的問(wèn)題

    在上一個(gè)版本中,對(duì)于無(wú)法找到Controller的問(wèn)題,是通過(guò)BundleContextAware來(lái)解決的,因?yàn)樗窃赟pring-OSGi中完成,因此其本質(zhì)就是修改ClassLoader來(lái)解決的。
    而更好的解決辦法其實(shí)是export controller所在的package,使用動(dòng)態(tài)引入功能,因?yàn)镾pring-bean都是通過(guò)Spring-core中的ClassUtils.forName來(lái)查找的。

    4. DispatcherServlet中的URI-Bean與osgi-bean引用的問(wèn)題

    DispatcherServlet dispatcherServlet = new DispatcherServlet();
        dispatcherServlet.setContextConfigLocation(
    "META-INF/dispatcher/petstore-servlet.xml");

    DispatcherServlet讀取配置文件中的bean,存放于DispatcherServlet的ApplicationContext的BeanFactory中,某個(gè)bean需要使用到OSGi的bean 引用時(shí),例如:
    <osgi:reference id="petStoreOsgi"
            interface
    ="org.extwind.osgi.demo.jpetstoreosgi.domain.logic.PetStoreFacade" />

    <bean name="/shop/viewCategory.do"
            class
    ="org.extwind.osgi.demo.jpetstoreosgi.springmvc.controller.ViewCategoryController">
            
    <property name="petStore" ref="petStoreOsgi" />
        
    </bean>

    可以看到/shop/viewCategory.do是一個(gè)bean,它被保存在DispatcherServlet的ApplicationContext中,
    osgi bean引用petStoreOsgi是存放在bundle的ApplicationContext中,這2個(gè)ApplicationContext并沒有關(guān)聯(lián),因此無(wú)法找到。

    這個(gè)兩個(gè)ApplicationContext的創(chuàng)建順序是這樣的:
    1. 程序中注冊(cè)DispatcherServlet后,它被初始化時(shí)創(chuàng)建ApplicationContext,加載contextConfigLocation中定義的bean
    2. Spring-OSGi當(dāng)監(jiān)聽到bundle started的事件時(shí),為該bundle創(chuàng)建ApplicationContext,加載bundle中/META-INF/spring/*.xml中定義的bean

    因此,這個(gè)問(wèn)題的解決辦法就是,讓DispatcherServlet的ApplicationContext在bundle的ApplicationContext之后創(chuàng)建,并設(shè)置成parent-child關(guān)系

    實(shí)際上這個(gè)問(wèn)題應(yīng)該是由mvc框架去考慮的,在Spring-OSGi的文檔中有解決方法,它是通過(guò)OsgiBundleXmlWebApplicationContext來(lái)實(shí)現(xiàn)的,也就是說(shuō)它無(wú)法在本例中使用,因?yàn)楫?dāng)DispatcherServlet被初始化時(shí),使用的Equinox的ServletConfig。

      > 如何讓bundle的ApplicationContext成為DispatcherServlet的ApplicationContext的parent?
         在DispatcherServlet的ApplicationContext在創(chuàng)建時(shí)的部分代碼如下:

    FrameworkServlet.java
    /**
         * Initialize and publish the WebApplicationContext for this servlet.
         * <p>Delegates to {
    @link #createWebApplicationContext} for actual creation
         * of the context. Can be overridden in subclasses.
         * 
    @return the WebApplicationContext instance
         * 
    @throws BeansException if the context couldn't be initialized
         * 
    @see #setContextClass
         * 
    @see #setContextConfigLocation
         
    */

        
    protected WebApplicationContext initWebApplicationContext() throws BeansException {
            WebApplicationContext wac 
    = findWebApplicationContext();
            
    if (wac == null{
                
    // No fixed context defined for this servlet - create a local one.
                WebApplicationContext parent =
                        WebApplicationContextUtils.getWebApplicationContext(getServletContext());
                wac 
    = createWebApplicationContext(parent);
            }


    WebApplicationContextUtils.java
    /**
         * Find the root WebApplicationContext for this web application, which is
         * typically loaded via {
    @link org.springframework.web.context.ContextLoaderListener} or
         * {
    @link org.springframework.web.context.ContextLoaderServlet}.
         * <p>Will rethrow an exception that happened on root context startup,
         * to differentiate between a failed context startup and no context at all.
         * 
    @param sc ServletContext to find the web application context for
         * 
    @return the root WebApplicationContext for this web app, or <code>null</code> if none
         * 
    @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
         
    */

        
    public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
            
    return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        }

          可以看到,使用的是ServletContext的屬性來(lái)存放ApplicationContext,因此在ApplicationContextAware.setApplicationContext(ApplicationContext bundleApplicationContext)中,可以通過(guò)下面的代碼來(lái)設(shè)置:
        
    HttpServlet tmpHttpServlet = new HttpServlet() {
                
    public void init(ServletConfig config) {
                    
    // config.getServletContext().setAttribute(OsgiBundleXmlWebApplicationContext.BUNDLE_CONTEXT_ATTRIBUTE,
                    
    // bundleContext);
                    OsgiBundleXmlWebApplicationContext webApplicationContext = new OsgiBundleXmlWebApplicationContext() {
                        
    protected String[] getDefaultConfigLocations() {
                            
    return new String[0];
                        }

                    }
    ;
                    webApplicationContext.setParent(applicationContext);
                    webApplicationContext.setServletContext(config.getServletContext());
                    webApplicationContext.refresh();

                    config.getServletContext().setAttribute(
                            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
                            webApplicationContext);
                }

            }
    ;
            httpService.registerServlet(
    "/init-context-loader-petsore-web", tmpHttpServlet, null,
                    httpContext);

        讓tmpHttpServlet和DispatcherServlet具有相同的HttpContext,那么DispatcherServlet就可以得到parent-ApplicationContext了。


        >如何讓DispatcherServlet的ApplicationContext在bundle的ApplicationContext之后創(chuàng)建?

    按照上一個(gè)版本中的方法,使用spring中的ApplicationContextAware接口,在這個(gè)接口的setParentApplicationContext方法之后,進(jìn)行資源注冊(cè)。
    這里需要注意的是在bundle停止時(shí)注銷注冊(cè)的資源


    以上幾點(diǎn)基本就是在新版中遇到的問(wèn)題。

    Demo下載: http://extwind.googlecode.com/svn/JPetStoreOSGi_Workspace.rar

    如何使用這個(gè)Demo:
    建議新建一個(gè)workspace,java編譯器需要6.0版本
    將所有的bundles導(dǎo)入后,需要再將 org.extwind.osgi.demo.jpetstoreosgi.launcher 導(dǎo)入
    本例中不包含DB數(shù)據(jù),因此還需要準(zhǔn)備Spring 2.5.6中的jpetstore
    運(yùn)行 spring-framework-2.5.6\samples\jpetstore\db\hsqldb\server.bat
    在Eclipse中運(yùn)行 org.extwind.osgi.demo.jpetstoreosgi.launcher.Launcher
    訪問(wèn)首頁(yè)地址:http://localhost/shop/index.do

    -----------------------------------------------------------------------------------------------------------

    稍后將介紹如何在Tomcat-OSGi中使用JPetStoreOSGi
    posted on 2009-04-19 03:31 Phrancol Yang 閱讀(4486) 評(píng)論(6)  編輯  收藏 所屬分類: OSGI

    FeedBack:
    # re: Tomcat-OSGi Demo: JPetStoreOSGi(Spring-osgi 1.2.0) [未登錄] 2009-06-05 17:46 tiger
    樓主,Demo無(wú)法下載啊  回復(fù)  更多評(píng)論
      
    # re: Tomcat-OSGi Demo: JPetStoreOSGi(Spring-osgi 1.2.0)  2009-06-05 19:39 Phrancol Yang
    @tiger
    已更新鏈接  回復(fù)  更多評(píng)論
      
    # re: Tomcat-OSGi Demo: JPetStoreOSGi(Spring-osgi 1.2.0)  2009-06-17 15:15 夢(mèng)醒
    為什么會(huì)出現(xiàn)下面異常。。。。。。。。。。。。。。。。。。。
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManagerOsgi': Invocation of init method failed; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.jdbc.datasource.DataSourceTransactionManager] for bean with name 'transactionManager' defined in URL [bundleentry://122/META-INF/spring/dataaccessContext.xml]: problem with class file or dependent class; nested exception is java.lang.NoClassDefFoundError: org.springframework.jdbc.datasource.DataSourceTransactionManager not found from bundle [Dataaccess Plug-in (com.futuresoftware.jpetstore.dataaccess)]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:423)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)
    at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
    at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:136)
    at java.lang.Thread.run(Unknown Source)
    Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.jdbc.datasource.DataSourceTransactionManager] for bean with name 'transactionManager' defined in URL [bundleentry://122/META-INF/spring/dataaccessContext.xml]: problem with class file or dependent class; nested exception is java.lang.NoClassDefFoundError: org.springframework.jdbc.datasource.DataSourceTransactionManager not found from bundle [Dataaccess Plug-in (com.futuresoftware.jpetstore.dataaccess)]
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1144)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getType(AbstractBeanFactory.java:487)
    at org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean.afterPropertiesSet(OsgiServiceFactoryBean.java:171)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
    ... 17 more  回復(fù)  更多評(píng)論
      
    # re: Tomcat-OSGi Demo: JPetStoreOSGi(Spring-osgi 1.2.0)  2009-07-01 23:03 Phrancol Yang
    @夢(mèng)醒

    java.lang.NoClassDefFoundError: org.springframework.jdbc.datasource.DataSourceTransactionManager not found from bundle [Dataaccess Plug-in (com.futuresoftware.jpetstore.dataaccess)]

    在你的bundle中import這個(gè)package: org.springframework.jdbc.datasource  回復(fù)  更多評(píng)論
      
    # re: Tomcat-OSGi Demo: JPetStoreOSGi(Spring-osgi 1.2.0)  2009-07-08 14:11 夢(mèng)醒
    JSTL.jar中的javax.servlet.jsp.jstl.core包全部也引入了,為什么在訪問(wèn)頁(yè)面時(shí)還會(huì)出現(xiàn)下面錯(cuò)誤,希望能加我的QQ給說(shuō)一下:8495138 謝謝

    org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:924)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:596)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
    at org.eclipse.equinox.http.servlet.internal.ServletRegistration.handleRequest(ServletRegistration.java:90)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:111)
    at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:75)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
    at org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet.service(HttpServerManager.java:269)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:428)
    at org.mortbay.jetty.servlet.ServletHandler.dispatch(ServletHandler.java:677)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:568)
    at org.mortbay.http.HttpContext.handle(HttpContext.java:1530)
    at org.mortbay.http.HttpContext.handle(HttpContext.java:1482)
    at org.mortbay.http.HttpServer.service(HttpServer.java:909)
    at org.mortbay.http.HttpConnection.service(HttpConnection.java:820)
    at org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:986)
    at org.mortbay.http.HttpConnection.handle(HttpConnection.java:837)
    at org.mortbay.http.SocketListener.handleConnection(SocketListener.java:245)
    at org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:357)
    at org.mortbay.util.ThreadPool$PoolThread.run(ThreadPool.java:534)
    Caused by: java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
    at org.springframework.web.servlet.support.JstlUtils.exposeLocalizationContext(JstlUtils.java:97)
    at org.springframework.web.servlet.view.JstlView.exposeHelpers(JstlView.java:133)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:209)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:257)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1183)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:902)
    ... 22 more
    Caused by: java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:405)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:393)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:105)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    ... 28 more
    12:02:32,883 DEBUG org.springframework.web.context.support.XmlWebApplicationContext:272 - Publishing event in context [org.springframework.web.context.support.XmlWebApplicationContext@834cfb]: ServletRequestHandledEvent: url=[/shop/index.do]; client=[127.0.0.1]; method=[GET]; servlet=[petstore]; session=[null]; user=[null]; time=[204ms]; status=[failed: org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config]
    12:02:32,883 DEBUG com.futuresoftware.usap.jpetstore.springmvc.DefaultHttpServiceRegister$1$1:272 - Publishing event in context [com.futuresoftware.usap.jpetstore.springmvc.DefaultHttpServiceRegister$1$1@8fcc7b]: ServletRequestHandledEvent: url=[/shop/index.do]; client=[127.0.0.1]; method=[GET]; servlet=[petstore]; session=[null]; user=[null]; time=[204ms]; status=[failed: org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config]
    12:02:32,883 DEBUG org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext:272 - Publishing event in context [org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@62610b]: ServletRequestHandledEvent: url=[/shop/index.do]; client=[127.0.0.1]; method=[GET]; servlet=[petstore]; session=[null]; user=[null]; time=[204ms]; status=[failed: org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config]
      回復(fù)  更多評(píng)論
      
    # re: Tomcat-OSGi Demo: JPetStoreOSGi(Spring-osgi 1.2.0)  2009-09-27 17:35 夢(mèng)醒
    @Phrancol Yang
    有時(shí),并不是加包可以解決的,即使加了,還是那樣。。。我感覺是類加載的問(wèn)題。。。。  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 久久久精品国产亚洲成人满18免费网站| 亚洲一区电影在线观看| 亚洲va国产va天堂va久久| 久久被窝电影亚洲爽爽爽| 久久精品国产亚洲av麻豆小说| 亚洲精品午夜在线观看| 国产精品亚洲专区在线观看| 亚洲αⅴ无码乱码在线观看性色| 色噜噜狠狠色综合免费视频 | 亚洲一区综合在线播放| 亚洲最大黄色网站| 亚洲国产精华液2020| 一级白嫩美女毛片免费| 亚洲午夜免费视频| 野花高清在线观看免费3中文| 国产在线ts人妖免费视频| 亚洲中文字幕无码中文字在线 | 亚洲精品视频免费观看| 久久久久亚洲av无码专区导航| 亚洲人成7777| 一级毛片免费不卡| 曰批全过程免费视频播放网站| 免费黄网在线观看| 亚洲日本乱码在线观看| youjizz亚洲| 一级毛片a女人刺激视频免费| 免费观看无遮挡www的小视频| 可以免费观看一级毛片黄a | 亚洲精品视频在线看| 亚洲视频在线观看地址| 老司机精品视频免费| 一级毛片免费观看| 免费国产a国产片高清| 亚洲欧洲国产日韩精品| 亚洲AV无码一区二区三区性色| 国内永久免费crm系统z在线 | 亚洲日本乱码一区二区在线二产线| 男人的天堂av亚洲一区2区| 久久黄色免费网站| jizzjizz亚洲| 亚洲国产片在线观看|