Подключение внешних файлов в Docker
У меня есть проект по компиляции исходного кода на Java и тестированию его с помощью JUnit. Сам проект написан на Spring Boot и работает как сервер. В общем, для компиляции я использую компилятор javac и указываю ему путь через -cp до двух библиотек (так как с помощью JUnit тестируется, ему нужны junit.jar и hamcrest.jar). В итоге получается что то вроде javac -cp ../junit.jar;../hamcrest.jar className testClassName. Данная штука работает на локальном компьютере но при запуске в Docker, разумеется, перестает работать, потому что файлов junit.jar и hamcrest.jar он не находит, поэтому с помощью volumes в docker-compose.yml я сделал их внешними и он опять начал их видеть (с помощью Java кода я сделал код, который просматривает содержимое папки и запустил это в Docker, результат — compileta | 2021-05-11 13:08:51.418 INFO 1 --- [nio-8081-exec-1] r.d.c.u.CompiletaClassLoaderComponent : [modules/hamcrest.jar, modules/junit.jar] ) — то есть он видит эти два файла, но по каким-то магическим обстоятельствам javac всё равно не компилирует, причем сам javac работает (я пробывал компилировать без зависимостей от JUnit и всё отлично), так что проблема именно в этих бибилотеках.
В общем, задача не очень тривиальная, поэтому я не особо понимаю, что именно нужно приводить из программного кода или файлов — поэтому спрашивайте в комментариях, я оперативно отредактирую и добавлю, что нужно.
Итоговая команда выглядит примерно так
javac -cp modules/junit.jar;modules/hamcrest.jar /classes/f8809fab-cf93-4fe6-890b-2dffd16dd69c/Upper.java /classes/f8809
fab-cf93-4fe6-890b-2dffd16dd69c/SolutionTest.java
Команда на локальном компьютере выглядит так:
javac -cp modules/junit.jar;modules/hamcrest.jar src/main/resources/classes/9f70eb8c-1391-4c57-b38f-aeaa299c5aad/Upper.java src/main/resources/classes/9f70eb8c-1391-4c57-b38f-aeaa299c5aad/SolutionTest.java
docker-compose.yml
version: '3.7'
services:
db:
image: postgres
container_name: postgres
ports:
- 5432:5432
environment:
POSTGRES_USERNAME: postgres
POSTGRES_PASSWORD: 1234
POSTGRES_DB: dexterity
compileta:
container_name: compileta
image: compileta
command: java -jar compileta.jar --spring.profiles.active=dev
ports:
- 8081:8081
volumes:
- ./modules:/modules/
- ./clasess:/classes/
environment:
SERVER_PORT: 8081
COMPILE_CLASSESDIRECTORY: /classes/
COMPILE_MODULESDIRECTORY: /modules/
app:
build: .
container_name: dexterity
ports:
- 8080:8080
command: java -jar dexterity.jar --spring.profiles.active=dev
volumes:
- ./res/images:/avatars/
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/dexterity
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: 1234
COMPILETA_COMPILEURL: http://compileta:8081/compile
COMPILETA_COMPILALLURL: http://compileta:8081/compile_all
UPLOAD_IMAGESPATH: /avatars/
links:
- db
- compileta
Ошибка возникает следующая:
compileta | 2021-05-11 15:00:43.595 INFO 1 --- [nio-8081-exec-1] r.d.c.u.CompiletaClassLoaderComponent : javac -cp /modules/junit.jar;/modules/hamcrest.jar /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/Upper.java /classes/2cd
76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java
compileta | 2021-05-11 15:00:43.597 INFO 1 --- [nio-8081-exec-1] r.d.c.u.CompiletaClassLoaderComponent : [/modules/hamcrest.jar, /modules/junit.jar]
compileta | 2021-05-11 15:00:44.260 INFO 1 --- [nio-8081-exec-1] r.d.c.u.CompiletaClassLoaderComponent : /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java:1: error: package org.junit does not exist
compileta | import org.junit.Test; import static org.junit.Assert.assertEquals; import org.junit.runners.JUnit4;
compileta | ^
compileta | /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java:1: error: package org.junit does not exist
compileta | import org.junit.Test; import static org.junit.Assert.assertEquals; import org.junit.runners.JUnit4;
compileta | ^
compileta | /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java:1: error: static import only from classes and interfaces
compileta | import org.junit.Test; import static org.junit.Assert.assertEquals; import org.junit.runners.JUnit4;
compileta | ^
compileta | /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java:1: error: package org.junit.runners does not exist
compileta | import org.junit.Test; import static org.junit.Assert.assertEquals; import org.junit.runners.JUnit4;
compileta | ^
compileta | /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java:4: error: cannot find symbol
compileta | @Test public void testSomething() { assertEquals("HELLO",u.MakeUpperCase("hello")); } }
compileta | ^
compileta | symbol: class Test
compileta | location: class SolutionTest
compileta | /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java:4: error: cannot find symbol
compileta | @Test public void testSomething() { assertEquals("HELLO",u.MakeUpperCase("hello")); } }
compileta | ^
compileta | symbol: method assertEquals(String,String)
compileta | location: class SolutionTest
compileta | 6 errors
P.S. Каталог modules содержит эти две библиотеки
Ответы (1 шт):
Проблема в том, что формат параметра classpath для javac зависит от системы. А именно разделитель между путями к компонентам classpath в Windows - ;, а в linux - :.
В докере используется линукс и команда должна быть такой (обратите внимание на двоеточие в аргументе к -cp):
javac -cp /modules/junit.jar:/modules/hamcrest.jar /classes/2cd76dd5-aaf3-482b-a9d4-d6d187e1c094/Upper.java /classes/2cd
76dd5-aaf3-482b-a9d4-d6d187e1c094/SolutionTest.java
Используйте File.pathSeparatorChar при генерации команды, чтобы она была переносимой между системами.
Из-за этого javac воспринимает classpath неправильно и не находит библиотеки.