Mac环境下Docker执行Jar文件时SPARQL端点连接404错误求助
我来帮你梳理下这个问题的根源,这其实是Docker Compose环境里容器间网络寻址的典型误区,咱们一步步解决:
核心问题出在哪?
在Docker Compose创建的网络环境里,每个容器都是独立的网络个体——你Java容器里写的localhost,指的是Java容器自己,而不是你的Mac宿主机,更不是Virtuoso容器。这就是为什么你在Mac浏览器里能访问localhost:8890/sparql,但容器里跑Jar就报错的原因。
直接解决办法(一步到位)
修改你Java代码里的SPARQL端点地址,把http://localhost:8890/sparql换成:
QueryExecution qexec = QueryExecutionFactory.sparqlService("http://virtuoso:8890/sparql", queryString);
这里的virtuoso是你docker-compose.yml里定义的Virtuoso服务名称,Docker Compose会自动在内部网络里把这个服务名解析到Virtuoso容器的IP,容器之间直接用这个方式通信最可靠。
验证一下是否生效
你可以进入Java容器内部,先测试网络连通性:
docker exec -it Test_docker ping virtuoso
如果能ping通,说明网络没问题,再用curl测试SPARQL端点:
docker exec -it Test_docker curl http://virtuoso:8890/sparql
能正常返回内容的话,再跑你的Jar包就应该没问题了。
为什么之前的尝试没用?
localhost/127.0.0.1:在Java容器里指向容器自身,根本到不了Virtuoso服务- 宿主机IP(比如192.168.99.100):Mac上Docker Desktop的网络模式和Windows的Docker Toolbox不一样,容器访问宿主机需要用
host.docker.internal,但这不是容器间通信的正确姿势,远不如用服务名稳定 - 修改
DEFAULT_GRAPH:这个是Virtuoso内部的默认图配置,和容器间的网络访问完全没关系,改它自然解决不了问题
额外优化建议(可选)
如果Virtuoso启动比较慢,可能会出现Java容器启动了,但Virtuoso还没就绪的情况,你可以给docker-compose.yml加个健康检查,确保Virtuoso完全 ready 后再启动Java容器:
给virtuoso服务添加健康检查配置:
healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8890/sparql"] interval: 10s timeout: 5s retries: 5
然后修改jardemo_test的depends_on:
depends_on: virtuoso: condition: service_healthy
这样Java容器会等Virtuoso服务完全就绪后再启动,避免因服务未启动导致的连接失败。
内容的提问来源于stack exchange,提问作者vimalDev

