使用SSHJ从SFTP下载BAK文件至类路径供MSSQLServerContainer加载失败排查
解决MSSQLServerContainer无法识别类路径中新下载BAK文件的问题
这个错误的核心原因是Java类加载器不会自动扫描运行时新增的类路径资源:src/test/resources是源码目录,实际运行时类加载器读取的是编译后复制到target/test-classes的资源;而且即使你把文件写到src/test/resources,已启动的类加载器也不会重新扫描这个目录来发现新文件。下面是几个可行的解决方案:
方案1:直接下载到类加载器实际读取的目录
最直接的办法是跳过源码目录,把BAK文件直接下载到target/test-classes——这是类加载器真正会读取的资源目录。修改你的SSHJ代码中的目标路径:
final SSHClient ssh = new SSHClient(); establishConnection(ssh); SFTPClient sftp = ssh.newSFTPClient(); List<RemoteResourceInfo> files = sftp.ls("public"); for (RemoteResourceInfo file : files) { String remoteServerFileLocation = file.getPath(); // 直接下载到target/test-classes,类加载器能立即识别 sftp.get(remoteServerFileLocation, "target/test-classes"); } sftp.close(); ssh.disconnect();
这样下载完成后,类加载器可以直接找到文件,不需要额外刷新操作,原有的withClasspathResourceMapping代码可以保持不变。
方案2:触发构建工具同步资源到target
如果你需要保持src/test/resources目录的同步(比如后续需要提交文件到版本控制),可以在下载完成后执行构建工具的资源复制命令,把src目录的新文件同步到target。
Maven项目示例:
// 下载完成后执行Maven的process-resources命令 ProcessBuilder pb = new ProcessBuilder("mvn", "process-test-resources"); pb.directory(new File(System.getProperty("user.dir"))); // 指向项目根目录 Process process = pb.start(); int exitCode = process.waitFor(); if (exitCode != 0) { throw new RuntimeException("Failed to sync test resources to target directory"); }
Gradle项目示例:
ProcessBuilder pb = new ProcessBuilder("gradle", "processTestResources"); pb.directory(new File(System.getProperty("user.dir"))); Process process = pb.start(); int exitCode = process.waitFor(); if (exitCode != 0) { throw new RuntimeException("Failed to sync test resources to target directory"); }
执行完这个命令后,src/test/resources中的新文件会被复制到target/test-classes,类加载器就能找到它了。
方案3:绕开类加载器,用文件系统路径绑定
另一种思路是不依赖类加载器,直接用磁盘文件路径来绑定到容器。修改容器启动代码,替换withClasspathResourceMapping为withFileSystemBind:
// 构造本地文件对象 File backupFile = new File("src/test/resources/" + BACKUP_FILE_NAME); // 用文件系统路径绑定,而非类路径资源 xMSSQLServerContainer.withFileSystemBind( backupFile.getAbsolutePath(), BACKUP_FILE_PATH, BindMode.READ_ONLY ).start();
这种方式直接读取磁盘上的文件,完全不受类加载器的限制,只要文件下载完成,容器就能立即访问到。
内容的提问来源于stack exchange,提问作者Pradeep
相关产品推荐
相关产品推荐

