下载 tomcat 10 源码,解压然后idea导入
包存放的默认位置如下:base.path=${user.home}/tomcat-build-libs
同时在项目的 tomcat/res/ide-support/idea/tomcat.iml
文件中提供了jar的依赖配置方式, 可以覆盖 .idea
配置,但对于 社区版有些插件是无法安装的,就从 ${user.home}/tomcat-build-libs
手动导入 jar 包
参考
ant 二进制包下载 后添加环境变量 %ANT_HOME%\bin
,idea2023 会自动识别, 或者打开 help-> action 搜索 ant
build.properties.default
,将其复制为 build.properties
ant
侧边栏,点击“+”,选择tomcat下的build.xml文件点击 ant 窗口的运行按钮
在输出目录下的 build/bin
运行 startup.bat
在浏览器 http://localhost:8080/
导入 ant 依赖
导入 ${user.home}/tomcat-build-libs
下的依赖
针对 java lang ClassNotFoundException listeners ContextListener
错误,是由于在idea的maven项目中要将java文件编译,加载进内存需要将文件夹设置为Sources Root
在 java/org/apache/catalina/startup/Bootstrap.java
中,自己调试运行
代码路径 java/org/apache/catalina/startup/Tomcat.java
public static void main(String[] args) throws Exception {
// Process some command line parameters
String[] catalinaArguments = null;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("--no-jmx")) {
Registry.disableRegistry();
} else if (args[i].equals("--catalina")) {
// This was already processed before
// Skip the rest of the arguments as they are for Catalina
ArrayList<String> result = new ArrayList<>();
for (int j = i + 1; j < args.length; j++) {
result.add(args[j]);
}
catalinaArguments = result.toArray(new String[0]);
break;
}
}
SecurityClassLoad.securityClassLoad(Thread.currentThread().getContextClassLoader());
Tomcat tomcat = new Tomcat();
// Create a Catalina instance and let it parse the configuration files
// It will also set a shutdown hook to stop the Server when needed
// Use the default configuration source
tomcat.init(null, catalinaArguments);
boolean await = false;
String path = "";
// Process command line parameters
for (int i = 0; i < args.length; i++) {
if (args[i].equals("--war")) {
if (++i >= args.length) {
throw new IllegalArgumentException(sm.getString("tomcat.invalidCommandLine", args[i - 1]));
}
File war = new File(args[i]);
tomcat.addWebapp(path, war.getAbsolutePath());
} else if (args[i].equals("--path")) {
if (++i >= args.length) {
throw new IllegalArgumentException(sm.getString("tomcat.invalidCommandLine", args[i - 1]));
}
path = args[i];
} else if (args[i].equals("--await")) {
await = true;
} else if (args[i].equals("--no-jmx")) {
// This was already processed before
} else if (args[i].equals("--catalina")) {
// This was already processed before
// Skip the rest of the arguments as they are for Catalina
break;
} else {
throw new IllegalArgumentException(sm.getString("tomcat.invalidCommandLine", args[i]));
}
}
tomcat.start();
// Ideally the utility threads are non daemon
if (await) {
tomcat.getServer().await();
}
}
在 conf/tomcat-users.xml
添加用户
<user username="admin" password="admin" roles="manager-gui,admin-gui,tomcat"/>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.apache.tomcatgroupId>
<artifactId>apache-tomcat-10.1.16-srcartifactId>
<name>Tomcatname>
<version>10.1.16version>
<build>
<finalName>apache-tomcat-10.1.16-srcfinalName>
<sourceDirectory>javasourceDirectory>
<resources>
<resource>
<directory>javadirectory>
resource>
resources>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.1version>
<configuration>
<encoding>UTF-8encoding>
<source>11source>
<target>11target>
configuration>
plugin>
plugins>
build>
<dependencies>
<dependency>
<groupId>geronimo-specgroupId>
<artifactId>geronimo-spec-jaxrpcartifactId>
<version>1.1-rc4version>
dependency>
<dependency>
<groupId>wsdl4jgroupId>
<artifactId>wsdl4jartifactId>
<version>1.6.3version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.hamcrestgroupId>
<artifactId>hamcrestartifactId>
<version>2.2version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.easymockgroupId>
<artifactId>easymockartifactId>
<version>4.3version>
dependency>
<dependency>
<groupId>cglibgroupId>
<artifactId>cglibartifactId>
<version>3.3.0version>
dependency>
<dependency>
<groupId>org.objenesisgroupId>
<artifactId>objenesisartifactId>
<version>3.3version>
dependency>
<dependency>
<groupId>com.unboundidgroupId>
<artifactId>unboundid-ldapsdkartifactId>
<version>6.0.10version>
dependency>
<dependency>
<groupId>com.puppycrawl.toolsgroupId>
<artifactId>checkstyleartifactId>
<version>10.12.4version>
dependency>
<dependency>
<groupId>org.jacocogroupId>
<artifactId>org.jacoco.agentartifactId>
<version>0.8.11version>
dependency>
<dependency>
<groupId>com.github.spotbugsgroupId>
<artifactId>spotbugsartifactId>
<version>4.8.0version>
<type>pomtype>
dependency>
<dependency>
<groupId>biz.aQute.bndgroupId>
<artifactId>biz.aQute.bndlibartifactId>
<version>7.0.0version>
dependency>
<dependency>
<groupId>org.apache.tomcatgroupId>
<artifactId>jakartaee-migrationartifactId>
<version>1.0.7version>
dependency>
<dependency>
<groupId>net.jsigngroupId>
<artifactId>jsign-coreartifactId>
<version>5.0version>
dependency>
<dependency>
<groupId>org.apache.derbygroupId>
<artifactId>derbyartifactId>
<version>10.16.1.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>antgroupId>
<artifactId>antartifactId>
<version>1.7.0version>
dependency>
<dependency>
<groupId>org.eclipse.jdtgroupId>
<artifactId>ecjartifactId>
<version>3.36.0version>
dependency>
<dependency>
<groupId>org.apache.tomcatgroupId>
<artifactId>tomcat-juliartifactId>
<version>11.0.0-M14version>
dependency>
dependencies>
project>
public class EmbeddedTomcat {
private static void resetLogging() {
final String loggingConfig = "handlers = java.util.logging.ConsoleHandler\n" +
".handlers = java.util.logging.ConsoleHandler\n" +
"java.util.logging.ConsoleHandler.level = FINE\n" +
"java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter\n" +
"java.util.logging.ConsoleHandler.encoding = UTF-8\n";
try {
InputStream is = new ByteArrayInputStream(loggingConfig.getBytes(StandardCharsets.UTF_8));
LogManager.getLogManager().readConfiguration(is);
LogFactory.getLog(EmbeddedTomcat.class).info("Logger configured to System.out");
} catch (SecurityException | IOException e) {
// Ignore, the VM default will be used
}
}
public static void main(String... args) throws Exception {
Registry.disableRegistry();
Tomcat tomcat = new Tomcat();
resetLogging();
tomcat.setPort(8080);
Connector connector = tomcat.getConnector();
connector.setProperty("bindOnInit", "false");
// No file system docBase required
Context ctx = tomcat.addContext("", null);
skipTldsForResourceJars(ctx);
CounterServlet counterServlet = new CounterServlet();
Tomcat.addServlet(ctx, "counterServlet", counterServlet);
ctx.addServletMappingDecoded("/", "counterServlet");
//ctx.addApplicationListener(new WsContextListener());
tomcat.start();
Thread.sleep(60*1000);
}
public static void skipTldsForResourceJars(Context context) {
StandardJarScanner scanner = (StandardJarScanner) context.getJarScanner();
StandardJarScanFilter filter = (StandardJarScanFilter) scanner.getJarScanFilter();
filter.setTldSkip(filter.getTldSkip() + ",resources*.jar");
}
private static class CounterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private AtomicInteger callCount = new AtomicInteger(0);
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.getSession(true);
resp.setContentType("text/plain");
resp.getWriter().print("OK: " + req.getRequestURL() + "[" + callCount.incrementAndGet()+ "]");
}
}
}