non proxied spring beans now refresh as expected
git-svn-id: https://svn.apache.org/repos/asf/myfaces/extensions/scripting/trunk@1401687 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/CompilationAwareRefreshableBeanFactory.java b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/CompilationAwareRefreshableBeanFactory.java
new file mode 100644
index 0000000..4f84472
--- /dev/null
+++ b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/CompilationAwareRefreshableBeanFactory.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.extensions.scripting.spring.bean;
+
+import org.apache.myfaces.extensions.scripting.core.common.util.ReflectUtil;
+import org.apache.myfaces.extensions.scripting.core.engine.ThrowAwayClassloader;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.CannotLoadBeanClassException;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.core.DecoratingClassLoader;
+import org.springframework.util.ClassUtils;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class CompilationAwareRefreshableBeanFactory extends DefaultListableBeanFactory
+{
+ public CompilationAwareRefreshableBeanFactory(BeanFactory parentBeanFactory)
+ {
+ super(parentBeanFactory);
+ }
+
+ public CompilationAwareRefreshableBeanFactory()
+ {
+ }
+
+ /**
+ * We have to set our throw away classloader
+ * here so that it is picked up by spring
+ *
+ * @param beanClassLoader
+ */
+ @Override
+ public void setBeanClassLoader(ClassLoader beanClassLoader)
+ {
+ if (!(beanClassLoader instanceof ThrowAwayClassloader))
+ {
+ super.setBeanClassLoader(new ThrowAwayClassloader(beanClassLoader));
+ } else
+ {
+ super.setBeanClassLoader(beanClassLoader);
+ }
+ }
+
+ @Override
+ protected Class resolveBeanClass(RootBeanDefinition mbd, String beanName)
+ {
+ //TODO drop the check whether the class has been loaded before
+ //and then resolve the class from the classloader
+
+ return super.resolveBeanClass(mbd, beanName);
+ }
+
+ @Override
+ protected Class resolveBeanClass(RootBeanDefinition beanDefinition, String beanName, Class[] typesToMatch) throws CannotLoadBeanClassException
+ {
+ try
+ {
+ // Note that this implementation doesn't check if the bean class has
+ // already been resolved previously (i.e. there's no check whether
+ // mbd.getBeanClass() is null). In doing so, it's possible to
+ // reload recompiled Class files.
+
+ if (typesToMatch != null)
+ {
+ ClassLoader tempClassLoader = getTempClassLoader();
+ if (tempClassLoader != null)
+ {
+ if (tempClassLoader instanceof DecoratingClassLoader)
+ {
+ DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
+ for (int i = 0; i < typesToMatch.length; i++)
+ {
+ dcl.excludeClass(typesToMatch[i].getName());
+ }
+ }
+ String className = beanDefinition.getBeanClassName();
+ return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
+ }
+ }
+
+ Class retVal = beanDefinition.resolveBeanClass(getBeanClassLoader());
+ try
+ {
+ //spring caches the constructor, we have to set it anew
+ //this imposes a limitation to () constructors but
+ //I guess we can live with it
+ Constructor ctor = retVal.getConstructor();
+ ReflectUtil.setField(beanDefinition,"resolvedConstructorOrFactoryMethod", ctor, true);
+ }
+ catch (NoSuchMethodException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+
+ return retVal;
+ }
+ catch (ClassNotFoundException ex)
+ {
+ throw new CannotLoadBeanClassException(
+ beanDefinition.getResourceDescription(), beanName, beanDefinition.getBeanClassName(), ex);
+ }
+ catch (LinkageError err)
+ {
+ throw new CannotLoadBeanClassException(
+ beanDefinition.getResourceDescription(), beanName, beanDefinition.getBeanClassName(), err);
+ }
+ }
+}
diff --git a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/RefreshableBeanAttribute.java b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/RefreshableBeanAttribute.java
new file mode 100644
index 0000000..23f4698
--- /dev/null
+++ b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/RefreshableBeanAttribute.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.extensions.scripting.spring.bean;
+
+import org.springframework.core.Conventions;
+
+/**
+ * <p>An attribute that will be attached to those bean definitions that are refreshable, i.e. this
+ * class contains some of the required metadata that you'll have to access if you want to decide
+ * whether a bean definition has to be refreshed or not. Note that this attribute, however, is
+ * only capable of determining whether a bean definition has to be refreshed, sometimes you'll
+ * actually have to refresh bean instances as well.</p>
+ */
+public class RefreshableBeanAttribute
+{
+
+ /**
+ * <p>The name of the bean definition metadata attribute that refers to an instance
+ * of this class, i.e. use this attribute name if you want to obtain all information
+ * regarding the last time that the bean definition has been refreshed.</p>
+ */
+ public static final String REFRESHABLE_BEAN_ATTRIBUTE =
+ Conventions.getQualifiedAttributeName(RefreshableBeanAttribute.class, "refreshableBeanAttribute");
+
+ /**
+ * <p>The timestamp in milliseconds of the last time that the bean
+ * definition that this attribute belongs to has been requested to
+ * refresh itself.</p>
+ */
+ private long refreshRequested;
+
+ /**
+ * <p>The timestamp in milliseconds of the last time that the bean
+ * definition that this attribute belongs to has been actually
+ * refreshed.</p>
+ */
+ private long refreshExecuted;
+
+ /**
+ * <p>By calling this method the user is able to request another refresh. Note that
+ * this doesn't cause the bean factory to refresh the bean definition immediately,
+ * but rather it just signals a request. The bean definition will be refreshed once
+ * the bean factory has to deal with the next bean request (i.e. a call to
+ * getBean()).</p>
+ */
+ public void requestRefresh()
+ {
+ refreshRequested = System.currentTimeMillis();
+ }
+
+ /**
+ * <p>Returns the timestamp in milliseconds of the last time that a refresh operation
+ * has been requested.</p>
+ *
+ * @return the timestamp in milliseconds of the last refresh request
+ */
+ public long getRequestedRefreshDate()
+ {
+ return refreshRequested;
+ }
+
+ /**
+ * <p>By calling this method the user indicates that the according bean definition
+ * has just been refreshed, which means that the method #{@link #requiresRefresh()}
+ * will return <code>false</code> until the user requests the next refresh.</p>
+ */
+ public void executedRefresh()
+ {
+ refreshExecuted = System.currentTimeMillis();
+ }
+
+ /**
+ * <p>Returns the timestamp in milliseconds of the last time that a refresh operation
+ * has been executed.</p>
+ *
+ * @return the timestamp in milliseconds of the last executed refresh operation
+ */
+ public long getExecutedRefreshDate()
+ {
+ return refreshExecuted;
+ }
+
+ /**
+ * <p>Determines whether a refresh is required, i.e. whether the user has requested
+ * another refresh operation by calling {@link #requestRefresh()} recently. Note that
+ * a call to this method only determines whether the bean definition on its own has
+ * to be refreshed (i.e. it doesn't even consider a particular bean instance).</p>
+ *
+ * @return whether a refresh call is required
+ */
+ public boolean requiresRefresh()
+ {
+ return getExecutedRefreshDate() < getRequestedRefreshDate();
+ }
+
+}
diff --git a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/RefreshableBeanFactory.java b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/RefreshableBeanFactory.java
new file mode 100644
index 0000000..82ef31c
--- /dev/null
+++ b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/bean/RefreshableBeanFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.extensions.scripting.spring.bean;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+
+/**
+ *
+ */
+public interface RefreshableBeanFactory extends ConfigurableListableBeanFactory
+{
+
+ /**
+ * <p>Requests a refresh operation for the definition of the bean with the given name. However,
+ * note that this doesn't necessarily mean that the bean definition gets refreshed immediatedly.
+ * Calling this method just ensures that the bean factory uses a refreshed bean definition by
+ * the next time you access the bean with the given name again.</p>
+ *
+ * @param name the name of the bean to refresh
+ * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
+ * if there is no bean with the given name
+ * @throws org.springframework.beans.factory.BeanDefinitionStoreException
+ * in case of an invalid bean definition
+ */
+ public void refreshBeanDefinition(String name) throws BeansException;
+
+ /**
+ * <p>Requests a refresh operation for definitions of beans with the given type. Again this
+ * doesn't necessarily mean that those bean definitions get refreshed immediately as calling
+ * this method just ensures that the bean factory uses a refreshed bean definition the next
+ * time you access one of those beans again.</p>
+ *
+ * @param className the type that you want to refresh beans for
+ * @param includeNonSingletons whether to include prototype or scoped beans too
+ * or just singletons (also applies to FactoryBeans)
+ * @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
+ * <i>objects created by FactoryBeans</i> (or by factory methods with a
+ * "factory-bean" reference) for the type check
+ * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
+ * if there is no bean with the given name
+ * @throws org.springframework.beans.factory.BeanDefinitionStoreException
+ * in case of an invalid bean definition
+ */
+ public void refreshBeanDefinitionsOfType(String className, boolean includeNonSingletons, boolean allowEagerInit)
+ throws BeansException;
+
+}
diff --git a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoader.java b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoader.java
index f5ef082..00ffc8f 100644
--- a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoader.java
+++ b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoader.java
@@ -23,6 +23,8 @@
import org.apache.myfaces.extensions.scripting.jsf.startup.StartupServletContextPluginChainLoader;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextException;
+import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
@@ -42,7 +44,14 @@
protected WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws BeansException
{
- WebApplicationContext retVal = super.createWebApplicationContext(servletContext, parent);
+ ConfigurableWebApplicationContext wac = new CompilationAwareXmlWebApplicationContext();
+
+ wac.setParent(parent);
+ wac.setServletContext(servletContext);
+ wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));
+ customizeContext(servletContext, wac);
+ wac.refresh();
+
//we now init the scripting system
try
{
@@ -50,8 +59,9 @@
//after the container is kickstarted
if (servletContext.getAttribute(RELOADING_LISTENER) == null)
{
+ //probably already started
StartupServletContextPluginChainLoader.startup(servletContext);
- servletContext.setAttribute(RELOADING_LISTENER, new ReloadingListener());
+ servletContext.setAttribute(RELOADING_LISTENER, new ReloadingListener(wac));
WeavingContext.getInstance().addListener((ReloadingListener) servletContext.getAttribute(RELOADING_LISTENER));
}
}
@@ -59,6 +69,21 @@
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
- return retVal;
+
+ Class contextClass = determineContextClass(servletContext);
+ if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass))
+ {
+ throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
+ "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
+ }
+
+ return wac;
}
+
+ @Override
+ public void closeWebApplicationContext(ServletContext servletContext)
+ {
+ super.closeWebApplicationContext(servletContext);
+ }
+
}
diff --git a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoaderListener.java b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoaderListener.java
index 89414ac..fc843d6 100644
--- a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoaderListener.java
+++ b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareContextLoaderListener.java
@@ -22,6 +22,8 @@
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.ContextLoaderListener;
+import javax.servlet.ServletContextEvent;
+
/**
* @author Werner Punz (latest modification by $Author$)
* @version $Revision$ $Date$
@@ -29,15 +31,40 @@
public class CompilationAwareContextLoaderListener extends ContextLoaderListener
{
+
+ public CompilationAwareContextLoaderListener()
+ {
+ super();
+ }
+
+ @Override
+ public void contextInitialized(ServletContextEvent event)
+ {
+ super.contextInitialized(event);
+ }
+
+ @Override
+ public ContextLoader getContextLoader()
+ {
+ return super.getContextLoader();
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ super.contextDestroyed(event);
+ }
+
/**
- * <p>Creates the context loader to use. Note that actually the context loader
- * starts up the web application context, this listener just delgates
- * to it.</p>
- *
- * @return the context loader to use to start up the web appplication context
- */
- @Override
- protected ContextLoader createContextLoader() {
- return new CompilationAwareContextLoader();
- }
+ * <p>Creates the context loader to use. Note that actually the context loader
+ * starts up the web application context, this listener just delgates
+ * to it.</p>
+ *
+ * @return the context loader to use to start up the web appplication context
+ */
+ @Override
+ protected ContextLoader createContextLoader()
+ {
+ return new CompilationAwareContextLoader();
+ }
}
diff --git a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareXmlWebApplicationContext.java b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareXmlWebApplicationContext.java
new file mode 100644
index 0000000..fcadf75
--- /dev/null
+++ b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/CompilationAwareXmlWebApplicationContext.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.extensions.scripting.spring.context;
+
+import org.apache.myfaces.extensions.scripting.spring.bean.CompilationAwareRefreshableBeanFactory;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.web.context.support.XmlWebApplicationContext;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class CompilationAwareXmlWebApplicationContext extends XmlWebApplicationContext
+{
+ public CompilationAwareXmlWebApplicationContext()
+ {
+ super();
+ }
+
+ /**
+ * Create an internal bean factory for this context.
+ * Called for each {@link #refresh()} attempt.
+ * <p>The default implementation creates a
+ * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory}
+ * with the {@link #getInternalParentBeanFactory() internal bean factory} of this
+ * context's parent as parent bean factory. Can be overridden in subclasses,
+ * for example to customize DefaultListableBeanFactory's settings.
+ *
+ * @return the bean factory for this context
+ * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
+ * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading
+ * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
+ * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
+ */
+ protected DefaultListableBeanFactory createBeanFactory()
+ {
+ return new CompilationAwareRefreshableBeanFactory(getInternalParentBeanFactory());
+ }
+}
diff --git a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/ReloadingListener.java b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/ReloadingListener.java
index d928341..23da7f1 100644
--- a/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/ReloadingListener.java
+++ b/extscript-core-root/extscript-spring/src/main/java/org/apache/myfaces/extensions/scripting/spring/context/ReloadingListener.java
@@ -21,12 +21,7 @@
import org.apache.myfaces.extensions.scripting.core.api.eventhandling.WeavingEvent;
import org.apache.myfaces.extensions.scripting.core.api.eventhandling.WeavingEventListener;
-import org.apache.myfaces.extensions.scripting.core.api.eventhandling.events.RefreshBeginEvent;
-import org.apache.myfaces.extensions.scripting.core.api.eventhandling.events.TaintedEvent;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.http.HttpServletRequest;
+import org.springframework.web.context.ConfigurableWebApplicationContext;
/**
* @author Werner Punz (latest modification by $Author$)
@@ -35,6 +30,13 @@
public class ReloadingListener implements WeavingEventListener
{
+ ConfigurableWebApplicationContext appContext = null;
+
+ public ReloadingListener(ConfigurableWebApplicationContext applicationContext)
+ {
+ appContext = applicationContext;
+ }
+
@Override
public void onEvent(WeavingEvent evt)
{
diff --git a/extscript-examples/spring-example/src/main/java/org/apache/myfaces/extension/scripting/spring/example/Greeter.java b/extscript-examples/spring-example/src/main/webapp/WEB-INF/java/org/apache/myfaces/extension/scripting/spring/example/Greeter.java
similarity index 100%
rename from extscript-examples/spring-example/src/main/java/org/apache/myfaces/extension/scripting/spring/example/Greeter.java
rename to extscript-examples/spring-example/src/main/webapp/WEB-INF/java/org/apache/myfaces/extension/scripting/spring/example/Greeter.java
diff --git a/extscript-examples/spring-example/src/main/java/org/apache/myfaces/extension/scripting/spring/example/Person.java b/extscript-examples/spring-example/src/main/webapp/WEB-INF/java/org/apache/myfaces/extension/scripting/spring/example/Person.java
similarity index 100%
rename from extscript-examples/spring-example/src/main/java/org/apache/myfaces/extension/scripting/spring/example/Person.java
rename to extscript-examples/spring-example/src/main/webapp/WEB-INF/java/org/apache/myfaces/extension/scripting/spring/example/Person.java
diff --git a/extscript-examples/spring-example/src/main/webapp/WEB-INF/web.xml b/extscript-examples/spring-example/src/main/webapp/WEB-INF/web.xml
index 41ac8a4..b5d0c7a 100644
--- a/extscript-examples/spring-example/src/main/webapp/WEB-INF/web.xml
+++ b/extscript-examples/spring-example/src/main/webapp/WEB-INF/web.xml
@@ -24,6 +24,15 @@
version="3.0">
<context-param>
+ <description>
+ Initializes the plugins for our scripting handlers
+ </description>
+ <param-name>org.apache.myfaces.FACES_INIT_PLUGINS</param-name>
+ <param-value>org.apache.myfaces.extensions.scripting.jsf.startup.StartupServletContextPluginChainLoader
+ </param-value>
+ </context-param>
+
+ <context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>