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 ...
Другие вопросы по тегам