Hi, I'm in the process of migrating embedded tomcat 7.0.59 application to Tomcat 8.0.20. Tomcat is been bundle as a OSGI bundle. First I get a NullPointerException when trying to access the server home page. I fixed that manually setting an empty TldCache instance in the context as follows
if(config.getServletContext().getAttribute("org.apache.jasper.compiler.TldCache") == null){ Constructor<?> constructor = Class.forName("org.apache.jasper.compiler.TldCache").getConstructor(ServletContext.class, Map.class, Map.class); Object instance = constructor.newInstance(config.getServletContext(), new HashMap<String, TldResourcePath>(), new HashMap<TldResourcePath, TaglibXml>()); config.getServletContext().setAttribute("org.apache.jasper.compiler.TldCache", instance); } Now it is not throwing the NPE. but instead of that I'm getting following exception org.apache.jasper.JasperException: The absolute uri: > http://tiles.apache.org/tags-tiles cannot be resolved in either web.xml > or the jar files deployed with this application > at > org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:55) > at > org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:277) > at > org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:75) > at > org.apache.jasper.compiler.TagLibraryInfoImpl.generateTldResourcePath(TagLibraryInfoImpl.java:240) > at > org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:124) > at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:411) > at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:469) > at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1430) > at org.apache.jasper.compiler.Parser.parse(Parser.java:139) > at > org.apache.jasper.compiler.ParserController.doParse(ParserController.java:227) > at > org.apache.jasper.compiler.ParserController.parse(ParserController.java:100) > at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:199) > at org.apache.jasper.compiler.Compiler.compile(Compiler.java:356) > at org.apache.jasper.compiler.Compiler.compile(Compiler.java:336) > at org.apache.jasper.compiler.Compiler.compile(Compiler.java:323) > at > org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:570) > at > org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:356) > at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) > at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) > at org.wso2.carbon.ui.JspServlet.service(JspServlet.java:175) > at org.wso2.carbon.ui.TilesJspServlet.service(TilesJspServlet.java:80) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) > at > org.eclipse.equinox.http.helper.ContextPathServletAdaptor.service(ContextPathServletAdaptor.java:37) > at > org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61) > at > org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128) > at > org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:68) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) > at > org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.service(DelegationServlet.java:64) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) > at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) > at > org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721) > at > org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:466) > at > org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:391) > at > org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318) > at > org.eclipse.equinox.http.servlet.internal.RequestDispatcherAdaptor.forward(RequestDispatcherAdaptor.java:30) > at > org.eclipse.equinox.http.helper.ContextPathServletAdaptor$RequestDispatcherAdaptor.forward(ContextPathServletAdaptor.java:362) > at > org.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:198) > at > org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:185) > at > org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:419) > at > org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:370) > at org.wso2.carbon.ui.action.ActionHelper.render(ActionHelper.java:52) > at org.wso2.carbon.ui.TilesJspServlet.service(TilesJspServlet.java:101) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) > at > org.eclipse.equinox.http.helper.ContextPathServletAdaptor.service(ContextPathServletAdaptor.java:37) > at > org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61) > at > org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128) > at > org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:68) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) > at > org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.service(DelegationServlet.java:64) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) > at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) > at > org.wso2.carbon.tomcat.ext.filter.CharacterSetFilter.doFilter(CharacterSetFilter.java:61) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) > at > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) > at > org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) > at > org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) > at > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) > at > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) > at > org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99) > at > org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49) > at > org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62) > at > org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:159) > at > org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) > at > org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57) > at > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) > at > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516) > at > org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086) > at > org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659) > at > org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223) > at > org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558) > at > org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > at > org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) > at java.lang.Thread.run(Thread.java:745) I'm also using a extended JarScanner as follows public class CarbonTomcatJarScanner extends StandardJarScanner{ private static final Log log = LogFactory.getLog(CarbonTomcatJarScanner.class); private static final Set<String> defaultJarsToSkip = new HashSet<String>(); private static final StringManager sm = StringManager.getManager(Constants.Package); private static final String CARBON_PLUGINS_DIR_PATH = System.getProperty("carbon.home") + "/repository/components/plugins"; static { String jarList = System.getProperty(Constants.SKIP_JARS_PROPERTY); if (jarList != null) { StringTokenizer tokenizer = new StringTokenizer(jarList, ","); while (tokenizer.hasMoreElements()) { defaultJarsToSkip.add(tokenizer.nextToken()); } } } /** * Controls the classpath scanning extension. */ private boolean scanClassPath = true; public boolean isScanClassPath() { return scanClassPath; } public void setScanClassPath(boolean scanClassPath) { this.scanClassPath = scanClassPath; } /** * Controls the testing all files to see of they are JAR files extension. */ private boolean scanAllFiles = false; public boolean isScanAllFiles() { return scanAllFiles; } public void setScanAllFiles(boolean scanAllFiles) { this.scanAllFiles = scanAllFiles; } /** * Controls the testing all directories to see of they are exploded JAR * files extension. */ private boolean scanAllDirectories = false; public boolean isScanAllDirectories() { return scanAllDirectories; } public void setScanAllDirectories(boolean scanAllDirectories) { this.scanAllDirectories = scanAllDirectories; } /* * Extract the JAR name, if present, from a URL */ private String getJarName(URL url) { String name = null; String path = url.getPath(); int end = path.indexOf(Constants.JAR_EXT); if (end != -1) { int start = path.lastIndexOf('/', end); name = path.substring(start + 1, end + 4); } else if (isScanAllDirectories()){ int start = path.lastIndexOf('/'); name = path.substring(start + 1); } return name; } @Override public void scan(JarScanType scanType, ServletContext context, JarScannerCallback callback){ Set<URL> processedURLs = new HashSet<>(); // Scan WEB-INF/lib Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB); if (dirList != null) { Iterator<String> it = dirList.iterator(); while (it.hasNext()) { String path = it.next(); if (path.endsWith(Constants.JAR_EXT) && getJarScanFilter().check(scanType, path.substring(path.lastIndexOf('/')+1))) { // Need to scan this JAR if (log.isDebugEnabled()) { log.debug(sm.getString("jarScan.webinflibJarScan", path)); } URL url = null; try { url = context.getResource(path); processedURLs.add(url); process(scanType, callback, url, path, true); } catch (IOException e) { log.warn(sm.getString("jarScan.webinflibFail", url), e); } } else { if (log.isTraceEnabled()) { log.trace(sm.getString("jarScan.webinflibJarNoScan", path)); } } } } // Scan WEB-INF/classes if (isScanAllDirectories()) { try { URL url = context.getResource("/WEB-INF/classes/META-INF"); if (url != null) { // Class path scanning will look at WEB-INF/classes since // that is the URL that Tomcat's web application class // loader returns. Therefore, it is this URL that needs to // be added to the set of processed URLs. URL webInfURL = context.getResource("/WEB-INF/classes"); if (webInfURL != null) { processedURLs.add(webInfURL); } try { callback.scanWebInfClasses(); } catch (IOException e) { log.warn(sm.getString("jarScan.webinfclassesFail"), e); } } } catch (MalformedURLException e) { // Ignore } } // Scan the classpath if (isScanClassPath()) { if (log.isTraceEnabled()) { log.trace(sm.getString("jarScan.classloaderStart")); } ClassLoader stopLoader = null; if (!isScanBootstrapClassPath()) { // Stop when we reach the bootstrap class loader stopLoader = ClassLoader.getSystemClassLoader().getParent(); } ClassLoader classLoader = Thread.currentThread().getContextClassLoader();//context.getClassLoader(); // JARs are treated as application provided until the common class // loader is reached. boolean isWebapp = true; while (classLoader != null /*&& classLoader != stopLoader*/) { if (classLoader instanceof URLClassLoader) { if (isWebapp) { isWebapp = isWebappClassLoader(classLoader); } URL[] urls = ((URLClassLoader) classLoader).getURLs(); for (int i=0; i<urls.length; i++) { if (processedURLs.contains(urls[i])) { // Skip this URL it has already been processed continue; } ClassPathEntry cpe = new ClassPathEntry(urls[i]); // JARs are scanned unless the filter says not to. // Directories are scanned for pluggability scans or // if scanAllDirectories is enabled unless the // filter says not to. if ((cpe.isJar() || scanType == JarScanType.PLUGGABILITY || isScanAllDirectories()) && getJarScanFilter().check(scanType, cpe.getName())) { if (log.isDebugEnabled()) { log.debug(sm.getString( "jarScan.classloaderJarScan", urls[i])); } try { process(scanType, callback, urls[i], null, isWebapp); } catch (IOException ioe) { log.warn(sm.getString( "jarScan.classloaderFail", urls[i]), ioe); } } else { // JAR / directory has been skipped if (log.isTraceEnabled()) { log.trace(sm.getString( "jarScan.classloaderJarNoScan", urls[i])); } } } } // WSO2 Carbon specific code snippet // Setting the plugins directory only if the parent classLoader is a bundleClassLoader. if (classLoader instanceof BundleClassLoader) { File pluginsDir = new File(CARBON_PLUGINS_DIR_PATH); File[] jarFiles = pluginsDir.listFiles(new FileFilter(){ public boolean accept(File file) { if(file.getName().endsWith(Constants.JAR_EXT)) { return true; } return false; } }); // processing collected jar files for tldListeners for (File jarFile : jarFiles) { try { if(jarFile.getName().contains("org.wso2.carbon.ui_4.4.0.SNAPSHOT")){ System.out.println("Here"); } process(scanType, callback, jarFile.toURI().toURL(),jarFile.getPath() ,isWebapp); } catch (IOException e) { log.warn(sm.getString("jarScan.classloaderFail"),e); } } } classLoader = classLoader.getParent(); } } } private boolean isWebappClassLoader(ClassLoader classLoader) { ClassLoader nonWebappLoader = StandardJarScanner.class.getClassLoader(); while (nonWebappLoader != null) { if (nonWebappLoader == classLoader) { return false; } nonWebappLoader = nonWebappLoader.getParent(); } return true; } /* * Scan a URL for JARs with the optional extensions to look at all files * and all directories. */ private void process(JarScanType scanType, JarScannerCallback callback, URL url, String webappPath, boolean isWebapp) throws IOException { if (log.isTraceEnabled()) { log.trace(sm.getString("jarScan.jarUrlStart", url)); } URLConnection conn = url.openConnection(); if (conn instanceof JarURLConnection) { callback.scan((JarURLConnection) conn, webappPath, isWebapp); } else { String urlStr = url.toString(); if (urlStr.startsWith("file:") || urlStr.startsWith("jndi:")) { if (urlStr.endsWith(Constants.JAR_EXT)) { URL jarURL = new URL("jar:" + urlStr + "!/"); callback.scan((JarURLConnection) jarURL.openConnection(), webappPath, isWebapp); } else { File f; try { f = new File(url.toURI()); if (f.isFile() && isScanAllFiles()) { // Treat this file as a JAR URL jarURL = new URL("jar:" + urlStr + "!/"); callback.scan( (JarURLConnection) jarURL.openConnection(), webappPath, isWebapp); } else if (f.isDirectory()) { if (scanType == JarScanType.PLUGGABILITY) { callback.scan(f, webappPath, isWebapp); } else { File metainf = new File(f.getAbsoluteFile() + File.separator + "META-INF"); if (metainf.isDirectory()) { callback.scan(f, webappPath, isWebapp); } } } } catch (URISyntaxException e) { // Wrap the exception and re-throw IOException ioe = new IOException(); ioe.initCause(e); throw ioe; } } } } } private static class ClassPathEntry { private final boolean jar; private final String name; public ClassPathEntry(URL url) { String path = url.getPath(); int end = path.indexOf(Constants.JAR_EXT); if (end != -1) { jar = true; int start = path.lastIndexOf('/', end); name = path.substring(start + 1, end + 4); } else { jar = false; if (path.endsWith("/")) { path = path.substring(0, path.length() - 1); } int start = path.lastIndexOf('/'); name = path.substring(start + 1); } } public boolean isJar() { return jar; } public String getName() { return name; } } } It seems that this is relate to JarScanner. Can someone tell me what I have done wrong here? Or a way to fix this? Is this occur because I set TldCache manually? Thanks Best Regards /Thusitha -- Thusitha Dayaratne Software Engineer WSO2 Inc. - lean . enterprise . middleware | wso2.com Mobile +94712756809 Blog alokayasoya.blogspot.com About http://about.me/thusithathilina