使用Docker部署Sling Bundle后遇404报错,请求排查问题
问题描述
尝试通过Docker镜像搭建Sling应用,操作步骤如下:
- 启动Docker镜像:
docker run --rm -p 8080:8080 apache/sling:snapshot - 创建Maven项目SlingSample,pom.xml配置如下:
<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.0</modelVersion> <groupId>com.example</groupId> <artifactId>SlingSample</artifactId> <version>1.0-SNAPSHOT</version> <packaging>bundle</packaging> <name>Sling Sample Bundle</name> <description>A sample Sling servlet bundle.</description> <dependencies> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> <version>2.23.0</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.servlets.annotations</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.service.component.annotations</artifactId> <version>1.4.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>5.1.8</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Activator>org.example.Activator</Bundle-Activator> <Export-Package>org.example.*</Export-Package> <Sling-Servlet-Paths>/bin/helloworld</Sling-Servlet-Paths> </instructions> </configuration> </plugin> </plugins> </build> </project>
- 编写HelloWorldServlet代码:
package com.example; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.servlets.HttpConstants; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.apache.sling.servlets.annotations.SlingServletPaths; import org.apache.sling.servlets.annotations.SlingServletResourceTypes; import org.osgi.service.component.annotations.Component; import javax.servlet.Servlet; import java.io.IOException; @Component(service = {Servlet.class}) @SlingServletPaths("/bin/helloworld") @SlingServletResourceTypes( resourceTypes = "sling/servlet/default", selectors = "HelloWorldServlet", extensions = "txt") public class HelloWorldServlet extends SlingAllMethodsServlet { @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { response.setContentType("text/plain"); response.getWriter().write("Hello, World!"); } }
- 执行
mvn clean install生成jar包; - 在容器中创建
/opt/sling/install目录,执行docker cp target/SlingSample-1.0-SNAPSHOT.jar <container_id>:/opt/sling/install/复制jar包。
遇到的问题:
- 访问
http://localhost:8080/bin/helloworld返回404错误:
Resource at '/bin/helloworld' not found: No resource found (404)
The requested URL /bin/helloworld resulted in an error in org.apache.sling.servlets.resolver.internal.defaults.DefaultErrorHandlerServlet.
- 在
http://localhost:8080/system/console/bundles中找不到SlingSample bundle。
排查与修复步骤
1. 移除不存在的Bundle Activator配置
pom.xml中配置了<Bundle-Activator>org.example.Activator</Bundle-Activator>,但未编写对应的org.example.Activator类,这会导致bundle无法被OSGi容器正常识别和启动。修改maven-bundle-plugin的instructions,删除这一行配置:
<!-- 移除该行 --> <Bundle-Activator>org.example.Activator</Bundle-Activator>
2. 使用Docker容器内的正确安装目录
apache/sling:snapshot镜像的默认监听安装目录是/app/sling/install,而非你创建的/opt/sling/install。先进入容器验证路径:
docker exec -it <container_id> bash ls /app/sling/install
重新复制jar包到正确路径:
docker cp target/SlingSample-1.0-SNAPSHOT.jar <container_id>:/app/sling/install/
3. 对齐依赖版本与Sling镜像版本
你使用的依赖版本(如org.apache.sling.api:2.23.0)较旧,与snapshot版本的Sling存在兼容性风险。建议通过Sling BOM统一管理依赖版本,在pom.xml中添加:
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.bom</artifactId> <version>12</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement>
然后移除各依赖的version标签,让BOM自动匹配兼容版本。
4. 简化Servlet注解配置
同时使用@SlingServletPaths和@SlingServletResourceTypes可能造成解析冲突,建议先保留单一配置测试。比如只保留路径注解:
@Component(service = {Servlet.class}) @SlingServletPaths("/bin/helloworld") public class HelloWorldServlet extends SlingAllMethodsServlet { // 原有doGet方法代码不变 }
5. 验证Bundle状态
复制jar包后,刷新http://localhost:8080/system/console/bundles,如果仍未找到目标bundle,查看容器日志排查具体错误:
docker logs <container_id>
日志会明确显示bundle加载失败的原因(如依赖缺失、类找不到等)。
内容的提问来源于stack exchange,提问作者ANAKHA ANIE JOSE 190768

