一键导入
dual-servlet-profiles
通过 Maven profiles 构建同时支持 javax.servlet-api 和 jakarta.servlet-api 的双版本 JAR,包含构建目录切换、finalName 自定义、依赖 jar 复制重命名
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
通过 Maven profiles 构建同时支持 javax.servlet-api 和 jakarta.servlet-api 的双版本 JAR,包含构建目录切换、finalName 自定义、依赖 jar 复制重命名
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | dual-servlet-profiles |
| description | 通过 Maven profiles 构建同时支持 javax.servlet-api 和 jakarta.servlet-api 的双版本 JAR,包含构建目录切换、finalName 自定义、依赖 jar 复制重命名 |
| source | auto-skill |
| extracted_at | 2026-06-29T08:46:44.229Z |
当项目需要在单代码仓库中同时产出 javax.servlet 和 jakarta.servlet 两个版本的 JAR 时,通过 Maven profiles 实现。
javax.servlet),下游迁移到 Tomcat 10+(jakarta.servlet)target/ vs target17/)将原来写在 <dependencies> 中的 servlet-api 删除,改为 profile 内的依赖。
<profile>
<id>javax</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
activeByDefault 确保不传 -P 时默认编译 javax 版本scope=provided:运行时由 servlet 容器提供<profile>
<id>jakarta</id>
<build>
<directory>target17</directory> <!-- 独立的输出目录 -->
<finalName>emp-script-ai-jdk17-${project.version}</finalName>
</build>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
关键点:
<directory> 覆盖默认的 target/,使 jakarta 产物不会覆盖 javax 产物<finalName> 修改 jar 文件名,添加 -jdk17 后缀便于区分当依赖的 artifact 也需要带 -jdk17 后缀时,在 jakarta profile 中添加:
<plugins>
<!-- 复制特定依赖 jar 到输出目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>copy-dep-emp</id>
<phase>package</phase>
<goals><goal>copy-dependencies</goal></goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<includeArtifactIds>emp-script,emp-script-utils</includeArtifactIds>
<excludeTransitive>true</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
<!-- 重命名为 *-jdk17-<version>.jar -->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>rename-dep-emp-jdk17</id>
<phase>package</phase>
<configuration>
<target>
<move todir="${project.build.directory}" verbose="true">
<fileset dir="${project.build.directory}">
<include name="emp-script-*.jar" />
<include name="emp-script-utils-*.jar" />
<exclude name="${project.build.finalName}.jar" />
<exclude name="*-last.jar" />
</fileset>
<mapper type="regexp"
from="^(emp-script(?:-utils)?)-(\d+\.\d+\.\d+.*?)(?:-jdk17)?\.jar$$"
to="\1-jdk17-\2.jar" />
</move>
</target>
</configuration>
<goals><goal>run</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
注意点:
-jdk17(如 emp-script-1.1.10-jdk17.jar)时,正则 (?:-jdk17)? 会 strip 掉再重新添加,确保统一为 emp-script-jdk17-1.1.10.jar 格式${project.build.finalName}.jar 和 *-last.jar,避免误处理主 jar主 build 中若使用了硬编码 target/ 路径(如 copy-rename-maven-plugin 的 sourceFile),应改为 ${project.build.directory}/,以便 profile 切换目录时自动适应。
# javax 版本 → target/emp-script-ai-1.0.0.jar
mvn -DskipTests package
# jakarta 版本 → target17/emp-script-ai-jdk17-1.0.0.jar
mvn -Pjakarta -DskipTests package
# 可与 release profile 叠加
mvn -Pjakarta,release -B package
当不希望记忆 -P 参数时,可将双 profile 拆分为两个独立 pom 文件,各专注一个 servlet 版本:
| 文件 | servlet 版本 | 输出目录 |
|---|---|---|
pom.xml | javax (默认激活) | target/ |
pomjdk17.xml | jakarta (默认激活) | target17/ |
pom.xml → pomjdk17.xmlpom.xml 只保留 javax profile,去除 jakarta profilepomjdk17.xml 只保留 jakarta profile(加 activeByDefault),去除 javax profile# javax 版本 → target/emp-script-ai-1.0.0.jar
mvn -f pom.xml -DskipTests package
# jakarta 版本 → target17/emp-script-ai-jdk17-1.0.0.jar
mvn -f pomjdk17.xml -DskipTests package
pomjdk17.xml 应与 pom.xml 保持相同的 <groupId>、<artifactId>、<version>,Maven 通过 <directory> 和 <finalName> 区分产物maven-dependency-plugin(复制依赖 jar)和 maven-antrun-plugin(重命名),确保它们的 execution id 不与主 build 中的 execution 冲突.gitignore 需添加 /target17/| 陷阱 | 解决 |
|---|---|
copy-rename-maven-plugin 硬编码 target/ | 替换为 ${project.build.directory}/ |
依赖版本已含 jdk17 字符串,rename 后双倍 | 正则用 (?:-jdk17)? 可选匹配并 strip |
多个 plugin execution ID 冲突(如两次 copy-lib-src-webapps) | 给 profile 内的 execution 不同 ID |
maven-antrun-plugin 在主 build 和 profile 中同时声明 | 版本号只需在主 build 声明一次,profile 内用 <artifactId>maven-antrun-plugin</artifactId>(无 version)自动继承 |
Architecture and implementation patterns for the AI API proxy/gateway module (switchproxy) that converts between OpenAI/Anthropic/Responses API formats, with IP access control, key-based auth, multi-host listening, HTML status page, Web admin UI, and tool config export
emp-script-ai 及其下游项目(travelagent、pf2023)所用 AI Mode XML schema 的撰写参考。覆盖 `<mode>` / `<step>` / `<prompt>` / `<apis>` / `<sqls>` / `<actions>` / `<paramChecks>` / `<ui>` 各块结构、prompt 数据源(sqlRef / api / action / CDATA)、函数调用 prompt(`apisCheck`)、URL / 请求占位符、输出自定义标签(`<day>`、`<rq>`、`<cid>`、`<enj>`、`<id>`、`<num>`、`<sersday>`、`<prices>`、`<gn>`)以及 step 控制属性(`innerCall`、`validateParams`、`multiOnlyUserMsg`、`action`、`actionSqlRef`)。
Debugging SSE streaming failures after refactoring AI provider code, focusing on JSON null-safety and field ordering
Setting up integrationTest framework with HSQLDB in-memory database and real AI APIs for emp-script-ai
Compare two SQL Server databases and sync missing tables and columns from source to target using sqlcmd and a Python script.
Procedure for adding a new AI provider to emp-script-ai (Java library wrapping multiple LLM providers via OpenAI-compatible interfaces)