Apple Silicon Mac上使用Testcontainers部署Oracle容器报错求助
解决Apple Silicon Mac上Spring 1.5.9集成Testcontainers+Oracle的问题
一、Oracle镜像对Apple Silicon的兼容性说明
- 官方Oracle Database镜像(如
oracle/database:11g、oracle/database:12c)无arm64架构版本,依赖Rosetta 2模拟x86_64环境运行时,极易出现架构不兼容错误(比如你遇到的UnsatisfiedLinkError)。 - 推荐使用社区维护的arm兼容Oracle镜像
gvenzl/oracle-xe,该镜像原生支持arm64架构,是轻量版Oracle XE,适配Apple Silicon芯片。
二、解决UnsatisfiedLinkError架构不兼容问题
方案1:替换为arm兼容镜像
直接将Testcontainers中的Oracle镜像替换为gvenzl/oracle-xe,示例代码:
@ClassRule public static OracleContainer oracleContainer = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim") .withUsername("test") .withPassword("test");
该镜像无需Rosetta模拟,可彻底避免原生库架构不匹配问题。
方案2:强制以x86_64模式运行(备选)
若必须使用官方镜像,需配置Colima以x86_64架构启动:
colima start --arch x86_64
同时注意Spring 1.5.9对应的Testcontainers版本建议选1.15.3,高版本可能不再兼容Spring 1.x。
三、解决Testcontainers找不到Colima Docker环境的问题
Testcontainers默认查找Docker Desktop的socket路径,Colima的socket路径不同,可通过以下两种方式配置:
方法1:设置环境变量
启动项目前执行:
export DOCKER_HOST=unix://$HOME/.colima/default/docker.sock export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock
也可直接在IDE的运行配置中添加这两个环境变量。
方法2:配置Testcontainers属性文件
在项目src/test/resources下创建testcontainers.properties,添加:
docker.host=unix://${user.home}/.colima/default/docker.sock testcontainers.docker.socket.override=/var/run/docker.sock
四、完整Spring 1.5.9 + Testcontainers + Oracle示例
1. Maven依赖配置(pom.xml)
<dependencies> <!-- Spring Test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>1.5.9.RELEASE</version> <scope>test</scope> </dependency> <!-- Testcontainers Oracle --> <dependency> <groupId>org.testcontainers</groupId> <artifactId>oracle-xe</artifactId> <version>1.15.3</version> <scope>test</scope> </dependency> <!-- Oracle JDBC Driver --> <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>19.3.0.0</version> <scope>test</scope> </dependency> </dependencies>
2. 测试类代码
import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.testcontainers.containers.OracleContainer; import javax.sql.DataSource; import static org.junit.Assert.assertEquals; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = TestConfig.class) public class OracleTest { @ClassRule public static OracleContainer oracleContainer = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim") .withUsername("TEST_USER") .withPassword("TEST_PWD"); private final JdbcTemplate jdbcTemplate; public OracleTest(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } @Test public void testOracleConnection() { // 创建测试表 jdbcTemplate.execute("CREATE TABLE TEST_TABLE (ID NUMBER, NAME VARCHAR2(255))"); // 插入数据 jdbcTemplate.update("INSERT INTO TEST_TABLE VALUES (?, ?)", 1, "Test"); // 查询验证 String name = jdbcTemplate.queryForObject("SELECT NAME FROM TEST_TABLE WHERE ID = ?", String.class, 1); assertEquals("Test", name); } }
3. Spring配置类(TestConfig.java)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DriverManagerDataSource; import javax.sql.DataSource; @Configuration public class TestConfig { @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("oracle.jdbc.OracleDriver"); dataSource.setUrl(OracleTest.oracleContainer.getJdbcUrl()); dataSource.setUsername(OracleTest.oracleContainer.getUsername()); dataSource.setPassword(OracleTest.oracleContainer.getPassword()); return dataSource; } }
内容的提问来源于stack exchange,提问作者skyho
相关产品推荐
相关产品推荐

