我最近通過參考https://blogs.nologin.es/rickyepoderi/index.php?/archives/44-Tomcat-7-and-the-Invoker-Servlet.html將我的 Tomcat 6 升級到 9.0.52
但是,該專案已成功部署在我的本地計算機上,我正在嘗試將我的專案部署到遠程服務器,但是每當我嘗試使用WAR檔案進行部署時,我的 tomcat 都會拋出“ HTTP 狀態 404 – 未找到”錯誤。但是,如果我直接從本地 Tomcat 復制 ROOT 檔案夾或使用 Eclipse 部署我的專案,則專案加載正常。
這是 localhost.out 檔案:
06-Dec-2021 15:04:21.712 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [test.ctxlistener.InvokerLoadListener]
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at test.ctxlistener.InvokerLoadListener.getClasses(Unknown Source)
at test.ctxlistener.InvokerLoadListener.contextInitialized(Unknown Source)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4768)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5230)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:698)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:690)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1889)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:583)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:473)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1618)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:319)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:946)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Catalina.start(Catalina.java:772)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476)
Caused by: java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:434)
at java.util.Properties.load0(Properties.java:353)
at java.util.Properties.load(Properties.java:341)
at test.connection.PooledDataSource.<clinit>(Unknown Source)
... 45 more
我檢查了我是否使用了任何舊的/不必要的 .jar 檔案,但這沒有幫助。我正在使用 JAVA 8 和 Ant 1.10.5。
我的 catalina.out 檔案中的錯誤副本也如下:
06-Dec-2021 15:04:21.712 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file 06-Dec-2021 15:04:21.712 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors 06-Dec-2021 15:04:21.759 INFO [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of deployment descriptor [C:\Apache-Tomcat\apache-tomcat-9.0.52\conf\Catalina\localhost\ROOT.xml] has finished in [5,703] ms 06-Dec-2021 15:04:21.759 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"] 06-Dec-2021 15:04:21.790 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-nio-8443"] 06-Dec-2021 15:04:21.806 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-127.0.0.1-8009"] 06-Dec-2021 15:04:21.806 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [5803] milliseconds
我不確定我在這里缺少什么。任何幫助將不勝感激。謝謝!
這是 invoker 的源代碼:
package test.ctxlistener;
import java.io.File;
import java.net.URL;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class InvokerLoadListener implements ServletContextListener {
/**
* Invoker parameter that defines the packages to search servlets.
* Comma separated list of packages
*/
public static final String PACKAGES_PARAMETER = "invoker.packages";
/**
* Invoker parameter to setup the mapping name. By default is "/servlet/"
*/
public static final String INVOKER_PREFIX_PARAMETER = "invoker.prefix";
/**
* Scans all classes accessible from the context class loader which
* belong to the given package and subpackages.
*
* @param packageName
* @return The list of classes found
*/
private List<Class<?>> getClasses(String packageName)
throws Exception {
String path = packageName.replace('.', '/');
ClassLoader classLoader = Thread.currentThread()
.getContextClassLoader();
assert classLoader != null;
Enumeration<URL> resources = classLoader.getResources(path);
List<String> dirs = new ArrayList<String>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(resource.getFile());
}
TreeSet<String> classes = new TreeSet<String>();
for (String directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
ArrayList<Class<?>> classList = new ArrayList<Class<?>>();
for (String clazz : classes) {
classList.add(Class.forName(clazz));
}
return classList;
}
private TreeSet<String> findClasses(String directory,
String packageName) throws Exception {
TreeSet<String> classes = new TreeSet<String>();
if (directory.startsWith("file:") && directory.contains("!")) {
String[] split = directory.split("!");
URL jar = new URL(split[0]);
try (ZipInputStream zip = new ZipInputStream(jar.openStream())) {
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
if (entry.getName().endsWith(".class")) {
String className = entry.getName()
.replaceAll("[$].*", "")
.replaceAll("[.]class", "")
.replace('/', '.');
if (className.startsWith(packageName)) {
classes.add(className);
}
}
}
}
}
File dir = new File(directory);
if (!dir.exists()) {
return classes;
}
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file.getAbsolutePath(),
packageName "." file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(packageName
'.'
file.getName().substring(0,
file.getName().length() - 6));
}
}
}
return classes;
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized(ServletContextEvent e)");
ServletContext sc = sce.getServletContext();
String list = sc.getInitParameter(PACKAGES_PARAMETER);
String prefix = sc.getInitParameter(INVOKER_PREFIX_PARAMETER);
if (prefix == null) {
prefix = "/servlet/";
}
if (list != null) {
String[] packages = list.split(",");
for (int i = 0; i < packages.length; i ) {
String packageName = packages[i].trim();
if (packageName.length() > 0) {
// load classes under servlet.invoker
System.out.println("Checking package: " packageName);
List<Class<?>> classes = null;
try {
classes = getClasses(packageName);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (Class clazz : classes) {
String mapping = prefix clazz.getName();
System.out.println(mapping);
ServletRegistration sr = sc.getServletRegistration(clazz.getName());
if ( sr == null ) {
sr = sc.addServlet(clazz.getName(), clazz.getName());}
if ( sr != null ) {
sr.addMapping(mapping);}
}
}
}
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed(ServletContextEvent e)");
}
}
uj5u.com熱心網友回復:
這是一個可能的答案。正如評論者@piotr-p-karwasz 所提到的,錯誤是由于 test.connection.PooledDataSource. 特別是它加載屬性檔案的位置。
at java.util.Properties.load(Properties.java:341)
這與java.util.Properties$LineReader.readLine非常相似
根據您的描述,如果您將整個 ROOT 檔案夾復制到應用程式啟動的新 Tomcat 服務器中,您應該檢查您的專案中是否存在組態檔(如 *.properties 檔案)以及是否正確添加通過 Ant 構建腳本添加到您的 WAR 檔案。您可以通過將 WAR 檔案解壓縮到臨時檔案夾中并將其內容與之前 Tomcat 版本中的 ROOT 檔案夾進行比較來完成此操作。
當您test.connection.PooledDataSource在問題中提供課程來源時,您將獲得更準確的答案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/381058.html
標籤:公猫
