Подключение внешних файлов в 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 шт):

Автор решения: Roman Konoval

Проблема в том, что формат параметра 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 неправильно и не находит библиотеки.

→ Ссылка