Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org')
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java162
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java59
-rw-r--r--jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java6
3 files changed, 178 insertions, 49 deletions
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java
index b88fda629d..7979d7bd47 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/ContainerTldBundleDiscoverer.java
@@ -27,10 +27,15 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
+import javax.servlet.jsp.JspFactory;
+
import org.eclipse.jetty.deploy.DeploymentManager;
+import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
@@ -39,15 +44,24 @@ import org.osgi.framework.FrameworkUtil;
/**
* ContainerTldBundleDiscoverer
*
+ * Finds bundles that are considered as on the container classpath that
+ * contain tlds.
+ *
+ * The System property org.eclipse.jetty.osgi.tldbundles is a comma
+ * separated list of exact symbolic names of bundles that have container classpath
+ * tlds.
*
- * Use a System property to define bundles that contain tlds that need to
- * be treated by jasper as if they were on the jetty container's classpath.
+ * The DeploymentManager context attribute "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern"
+ * can be used to define a pattern of symbolic names of bundles that contain container
+ * classpath tlds.
*
- * The value of the property is evaluated against the DeploymentManager
- * context attribute "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern",
- * which defines a pattern of matching bundle names.
+ * The matching bundles are converted to URLs that are put onto a special classloader that acts as the
+ * parent classloader for contexts deployed by the jetty Server instance (see ServerInstanceWrapper).
*
- * The bundle locations are converted to URLs for jasper's use.
+ * It also discovers the bundle that contains the jstl taglib and adds it into the
+ * "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern" (if it is not already there) so
+ * that the WebInfOSGiConfiguration class will add the jstl taglib bundle into the list of container
+ * resources.
*
* Eg:
* -Dorg.eclipse.jetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh
@@ -55,16 +69,20 @@ import org.osgi.framework.FrameworkUtil;
*/
public class ContainerTldBundleDiscoverer implements TldBundleDiscoverer
{
- /**
- * Comma separated list of names of bundles that contain tld files that should be
- * discoved by jasper as if they were on the container's classpath.
- * Eg:
- * -Djetty.osgi.tldbundles=org.springframework.web.servlet,com.opensymphony.module.sitemesh
- */
- public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles";
+ private static final Logger LOG = Log.getLogger(ContainerTldBundleDiscoverer.class);
+
+ private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl";
+ /**
+ * Default name of a class that belongs to the jstl bundle. From that class
+ * we locate the corresponding bundle and register it as a bundle that
+ * contains tld files.
+ */
+ private static String DEFAULT_JSTL_BUNDLE_CLASS = "org.apache.taglibs.standard.tag.el.core.WhenTag";
+ private Bundle jstlBundle = null;
+
/**
* Check the System property "org.eclipse.jetty.osgi.tldbundles" for names of
* bundles that contain tlds and convert to URLs.
@@ -72,19 +90,18 @@ public class ContainerTldBundleDiscoverer implements TldBundleDiscoverer
* @return The location of the jars that contain tld files as URLs.
*/
public URL[] getUrlsForBundlesWithTlds(DeploymentManager deploymentManager, BundleFileLocatorHelper locatorHelper) throws Exception
- {
- // naive way of finding those bundles.
- // lots of assumptions: for example we assume a single version of each
- // bundle that would contain tld files.
- // this is probably good enough as those tlds are loaded system-wide on
- // jetty.
- // to do better than this we need to do it on a per webapp basis.
- // probably using custom properties in the ContextHandler service
- // and mirroring those in the MANIFEST.MF
+ {
+ if (!isJspAvailable())
+ {
+ return new URL[0];
+ }
+
+ if (jstlBundle == null)
+ jstlBundle = findJstlBundle();
Bundle[] bundles = FrameworkUtil.getBundle(ContainerTldBundleDiscoverer.class).getBundleContext().getBundles();
HashSet<URL> urls = new HashSet<URL>();
- String tmp = System.getProperty(SYS_PROP_TLD_BUNDLES); //comma separated exact names
+ String tmp = System.getProperty(OSGiWebInfConfiguration.SYS_PROP_TLD_BUNDLES); //comma separated exact names
List<String> sysNames = new ArrayList<String>();
if (tmp != null)
{
@@ -93,13 +110,33 @@ public class ContainerTldBundleDiscoverer implements TldBundleDiscoverer
sysNames.add(tokenizer.nextToken());
}
tmp = (String) deploymentManager.getContextAttribute(OSGiWebInfConfiguration.CONTAINER_BUNDLE_PATTERN); //bundle name patterns
+
Pattern pattern = (tmp==null? null : Pattern.compile(tmp));
+
+ //check that the jstl bundle is not already included in the pattern, and include it if it is not because
+ //subsequent classes such as OSGiWebInfConfiguration use this pattern to determine which jars are
+ //considered to be on the container classpath
+ if (jstlBundle != null)
+ {
+ if (pattern == null)
+ {
+ pattern = Pattern.compile(jstlBundle.getSymbolicName());
+ deploymentManager.setContextAttribute(OSGiWebInfConfiguration.CONTAINER_BUNDLE_PATTERN, jstlBundle.getSymbolicName());
+ }
+ else if (!(pattern.matcher(jstlBundle.getSymbolicName()).matches()))
+ {
+ String s = tmp+"|"+jstlBundle.getSymbolicName();
+ pattern = Pattern.compile(s);
+ deploymentManager.setContextAttribute(OSGiWebInfConfiguration.CONTAINER_BUNDLE_PATTERN, s);
+ }
+ }
+
+
for (Bundle bundle : bundles)
{
if (sysNames.contains(bundle.getSymbolicName()))
- convertBundleLocationToURL(locatorHelper, bundle, urls);
-
- if (pattern != null && pattern.matcher(bundle.getSymbolicName()).matches())
+ convertBundleLocationToURL(locatorHelper, bundle, urls);
+ else if (pattern != null && pattern.matcher(bundle.getSymbolicName()).matches())
convertBundleLocationToURL(locatorHelper, bundle, urls);
}
@@ -108,6 +145,79 @@ public class ContainerTldBundleDiscoverer implements TldBundleDiscoverer
}
/**
+ * Check that jsp is on the classpath
+ * @return
+ */
+ public boolean isJspAvailable()
+ {
+ try
+ {
+ getClass().getClassLoader().loadClass("org.apache.jasper.servlet.JspServlet");
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Unable to locate the JspServlet: jsp support unavailable.", e);
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ *
+ * Some versions of JspFactory do Class.forName, which probably won't work in an
+ * OSGi environment.
+ */
+ public void fixJspFactory ()
+ {
+ try
+ {
+ Class<javax.servlet.ServletContext> servletContextClass = javax.servlet.ServletContext.class;
+ // bug #299733
+ JspFactory fact = JspFactory.getDefaultFactory();
+ if (fact == null)
+ { // bug #299733
+ // JspFactory does a simple
+ // Class.getForName("org.apache.jasper.runtime.JspFactoryImpl")
+ // however its bundles does not import the jasper package
+ // so it fails. let's help things out:
+ fact = (JspFactory) JettyBootstrapActivator.class.getClassLoader().loadClass(DEFAULT_JSP_FACTORY_IMPL_CLASS).newInstance();
+ JspFactory.setDefaultFactory(fact);
+ }
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Unable to set the JspFactory: jsp support incomplete.", e);
+ }
+ }
+
+
+ /**
+ * Find the bundle that contains a jstl implementation class, which assumes that
+ * the jstl taglibs will be inside the same bundle.
+ * @return
+ */
+ public Bundle findJstlBundle ()
+ {
+ Class<?> jstlClass = null;
+
+ try
+ {
+ jstlClass = JSTLBundleDiscoverer.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS);
+ }
+ catch (ClassNotFoundException e)
+ {
+ LOG.info("jstl not on classpath", e);
+ }
+
+ if (jstlClass != null)
+ //get the bundle containing jstl
+ return FrameworkUtil.getBundle(jstlClass);
+
+ return null;
+ }
+
+ /**
* Resolves a bundle that contains tld files as a URL. The URLs are
* used by jasper to discover the tld files.
*
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java
index 04cdc72420..3857664942 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jasper/JSTLBundleDiscoverer.java
@@ -20,9 +20,11 @@ package org.eclipse.jetty.osgi.boot.jasper;
import java.io.File;
import java.io.InputStream;
+import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.Set;
import javax.servlet.Servlet;
import javax.servlet.jsp.JspContext;
@@ -30,7 +32,6 @@ import javax.servlet.jsp.JspFactory;
import org.apache.jasper.Constants;
import org.apache.jasper.compiler.Localizer;
-import org.apache.jasper.xmlparser.ParserUtils;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
@@ -85,10 +86,12 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
* implementation. bug #299733
*/
private static String DEFAULT_JSP_FACTORY_IMPL_CLASS = "org.apache.jasper.runtime.JspFactoryImpl";
+
+ private static final Set<URL> __tldBundleCache = new HashSet<URL>();
public JSTLBundleDiscoverer()
{
- fixupDtdResolution();
+ //fixupDtdResolution();
try
{
@@ -102,6 +105,7 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
}
try
{
+ Class<javax.servlet.ServletContext> servletContextClass = javax.servlet.ServletContext.class;
// bug #299733
JspFactory fact = JspFactory.getDefaultFactory();
if (fact == null)
@@ -143,7 +147,7 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
{
ArrayList<URL> urls = new ArrayList<URL>();
- HashSet<Class<?>> classesToAddToTheTldBundles = new HashSet<Class<?>>();
+ Class<?> jstlClass = null;
// Look for the jstl bundle
// We assume the jstl's tlds are defined there.
@@ -151,18 +155,21 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
// So we can look for this class using this bundle's classloader:
try
{
- Class<?> jstlClass = JSTLBundleDiscoverer.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS);
-
- classesToAddToTheTldBundles.add(jstlClass);
+ jstlClass = JSTLBundleDiscoverer.class.getClassLoader().loadClass(DEFAULT_JSTL_BUNDLE_CLASS);
}
catch (ClassNotFoundException e)
{
LOG.info("jstl not on classpath", e);
}
- for (Class<?> cl : classesToAddToTheTldBundles)
+
+ if (jstlClass != null)
{
- Bundle tldBundle = FrameworkUtil.getBundle(cl);
+ //get the bundle containing jstl
+ Bundle tldBundle = FrameworkUtil.getBundle(jstlClass);
File tldBundleLocation = locatorHelper.getBundleInstallLocation(tldBundle);
+
+ System.err.println("jstl bundle: "+tldBundle);
+ System.err.println("jstl bundle location: "+tldBundleLocation);
if (tldBundleLocation != null && tldBundleLocation.isDirectory())
{
// try to find the jar files inside this folder
@@ -170,6 +177,7 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
{
if (f.getName().endsWith(".jar") && f.isFile())
{
+ System.err.println("Tld jar in dir: "+f.toURI());
urls.add(f.toURI().toURL());
}
else if (f.isDirectory() && f.getName().equals("lib"))
@@ -178,6 +186,7 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
{
if (f2.getName().endsWith(".jar") && f2.isFile())
{
+ System.err.println("Tld jar in lib dir: "+f2.toURI());
urls.add(f2.toURI().toURL());
}
}
@@ -187,9 +196,20 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
}
else if (tldBundleLocation != null)
{
+ System.err.println("Tld bundle uri: "+tldBundleLocation.toURI());
urls.add(tldBundleLocation.toURI().toURL());
+
+ String pattern = (String)deployer.getContextAttribute("org.eclipse.jetty.server.webapp.containerIncludeBundlePattern");
+ pattern = (pattern==null?"":pattern);
+ if (!pattern.contains(tldBundle.getSymbolicName()))
+ {
+ pattern += "|"+tldBundle.getSymbolicName();
+ deployer.setContextAttribute("org.eclipse.jetty.server.webapp.containerIncludeBundlePattern", pattern);
+ }
+ System.err.println("PATTERN: "+pattern);
}
}
+
return urls.toArray(new URL[urls.size()]);
}
@@ -209,11 +229,12 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
* new value on a static friendly field :(
* </p>
*/
- void fixupDtdResolution()
+ void fixupDtdResolution()
{
try
{
- ParserUtils.setEntityResolver(new MyFixedupEntityResolver());
+ // ParserUtils.setEntityResolver(new MyFixedupEntityResolver());
+
}
catch (Exception e)
@@ -227,21 +248,21 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
* Instead of using the ParserUtil's classloader, we use a class that is
* indeed next to the resource for sure.
*/
- static class MyFixedupEntityResolver implements EntityResolver
- {
+ //static class MyFixedupEntityResolver implements EntityResolver
+ //{
/**
* Same values than in ParserUtils...
*/
- static final String[] CACHED_DTD_PUBLIC_IDS = { Constants.TAGLIB_DTD_PUBLIC_ID_11, Constants.TAGLIB_DTD_PUBLIC_ID_12,
+ /* static final String[] CACHED_DTD_PUBLIC_IDS = { Constants.TAGLIB_DTD_PUBLIC_ID_11, Constants.TAGLIB_DTD_PUBLIC_ID_12,
Constants.WEBAPP_DTD_PUBLIC_ID_22, Constants.WEBAPP_DTD_PUBLIC_ID_23, };
static final String[] CACHED_DTD_RESOURCE_PATHS = { Constants.TAGLIB_DTD_RESOURCE_PATH_11, Constants.TAGLIB_DTD_RESOURCE_PATH_12,
Constants.WEBAPP_DTD_RESOURCE_PATH_22, Constants.WEBAPP_DTD_RESOURCE_PATH_23, };
static final String[] CACHED_SCHEMA_RESOURCE_PATHS = { Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20, Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21,
- Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24, Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25, };
+ Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24, Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25, };*/
- public InputSource resolveEntity(String publicId, String systemId) throws SAXException
+ /* public InputSource resolveEntity(String publicId, String systemId) throws SAXException
{
for (int i = 0; i < CACHED_DTD_PUBLIC_IDS.length; i++)
{
@@ -255,11 +276,11 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
{
input = JspContext.class.getResourceAsStream(resourcePath);
if (input == null)
- {
+ {*/
// if that failed try again with the original code:
// although it is likely not changed.
- input = this.getClass().getResourceAsStream(resourcePath);
- }
+ /* input = this.getClass().getResourceAsStream(resourcePath);
+ }
}
if (input == null) { throw new SAXException(Localizer.getMessage("jsp.error.internal.filenotfound", resourcePath)); }
InputSource isrc = new InputSource(input);
@@ -269,6 +290,6 @@ public class JSTLBundleDiscoverer implements TldBundleDiscoverer
return null;
}
- }
+ }*/
}
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
index d9bd9b69e8..7417580102 100644
--- a/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
+++ b/jetty-osgi/jetty-osgi-boot-jsp/src/main/java/org/eclipse/jetty/osgi/boot/jsp/FragmentActivator.java
@@ -18,17 +18,16 @@
package org.eclipse.jetty.osgi.boot.jsp;
-import org.eclipse.jetty.osgi.boot.BundleWebAppProvider;
+
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.osgi.boot.jasper.ContainerTldBundleDiscoverer;
-import org.eclipse.jetty.osgi.boot.jasper.JSTLBundleDiscoverer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
/**
* FragmentActivator
*
- * Sets up support for jsp. All relevant jsp jars must also be installed
+ * Sets up support for jsp and jstl. All relevant jsp jars must also be installed
* into the osgi environment.
* <p>
* Note that as this is part of a bundle fragment, this activator is NOT
@@ -54,7 +53,6 @@ public class FragmentActivator implements BundleActivator
//set up some classes that will look for bundles with tlds that must be converted
//to urls and treated as if they are on the Jetty container's classpath so that
//jasper can deal with them
- ServerInstanceWrapper.addContainerTldBundleDiscoverer(new JSTLBundleDiscoverer());
ServerInstanceWrapper.addContainerTldBundleDiscoverer(new ContainerTldBundleDiscoverer());
}

Back to the top