Makefile, основная функция, ClassNotFound
У меня есть Java-программа, и я пишу make-файл для компиляции в Linux.
Мой проект организован так (Run.java - главная запись)
Program -
Src -
(package)adb.Bing_WebResults
Run.java
(package)adb.jsonModel
*.java
(package)adb.models
*.java
bin -
lib -
gson.jar
commons.jar
resource -
*.txt
Это мой make-файл:
# My project require 3 parameters from user input.
default: Run.class
Run.class: src/adb/Bing_WebResults/Run.java
javac -sourcepath src/ -classpath lib/*.jar -d bin/ src/adb/Bing_WebResults/*.java src/adb/jsonModels/*.java src/adb/models/*.java
run:
java -classpath bin/:lib/*.jar Run "$(ARG1)" "$(ARG2)" "$(ARG3)"
Когда я использую команду "make run" в Linux terminate, исключение показывает, что "Не удалось найти основной класс: Run"
Что-то не так с моим make-файлом? Неправильный путь или что-то?
3 ответа
Есть много вещей, которые потенциально могут быть неправильными, но наиболее очевидные проблемы - неправильные зависимости целей в вашем make-файле.
Прежде всего, цель run
должен иметь зависимость от Run.class
, Если вы делаете make run
затем make
смотрит на цель под названием run
, В вашем makefile
эта цель не имеет никаких определенных зависимостей, и она выполнит строку java ...
без проверки, является ли фактический скомпилированный класс Run.class
существует. Как следствие, если вы делаете make run
из чистой ситуации, ваш исходный код не будет скомпилирован и java
Команда не будет выполнена, потому что скомпилированный класс отсутствует.
Ваша зависимость от default
на Run.class
также неверно, потому что Run.class
будет существовать в bin
каталог, а не в рабочем каталоге. В строке ниже упоминается цель Run.class
также.
Есть несколько способов улучшить ваш make-файл. Ниже приведен пример исправленного кода с добавлением некоторых переменных, чтобы избежать повторяющихся выражений. Этот подход - вопрос стиля и предпочтения.
BINDIR := bin
RUNCLASS := Run
RUNBINARY := $(BINDIR)/$(RUNCLASS).class
SRCDIR := src/adb/Bing_WebResults
RUNSRC := $(SRCDIR)/$(RUNCLASS).java
# Note: the default target below is superfluous at this moment
default: $(RUNBINARY)
$(RUNBINARY): $(RUNSRC)
javac -sourcepath src/ -classpath lib/*.jar -d $(BINDIR) $(SRCDIR)/*.java src/adb/jsonModels/*.java src/adb/models/*.java
run: $(RUNBINARY)
java -classpath $(BINDIR):lib/*.jar $(RUNCLASS) "$(ARG1)" "$(ARG2)" "$(ARG3)"
Это работает для меня в упрощенной, сопоставимой установке - это может работать и для вас. Глядя на предоставленный вами фрагмент, скорее всего, есть другие зависимости или изменения, которые необходимо добавить для завершения makefile
правильно. Потенциально вам может потребоваться добавить информацию о пакете в вашу команду запуска и выражения зависимостей, но это зависит от вашего исходного кода. Ваше сообщение не содержит достаточно информации, чтобы обеспечить полное решение.
PS: не забудьте заменить пробелы на вкладки, если вы копируете этот код на свой makefile
,
Оказывается, следует обратить внимание на два момента: (1) Run находится в пакете, поэтому он должен быть "adb.Bing_WebResults.Run.class" в make-файле.
(2) внешние файлы jar должны быть объединены с помощью: (например, lib/a.jar: lib/b.jar)
Наконец, вам нужно указать пакет при запуске, так как у вас нет основного класса в пакете по умолчанию.
java -classpath bin com.example.Run arg1 arg2 ...