Перейти к содержимому

Как скомпилировать java в class

  • автор:

Как скомпилировать java в class

Java – это компилируемый язык программирования, поэтому файл с исходным кодом сначала нужно превратить в байткод, прежде чем запускать. Это делается при помощи компилятора javac. Предположим, у нас есть файл HelloWorld.java с таким кодом:

// Файл HelloWorld.java class HelloWorld  public static void main(String[] args)  System.out.println("Hello, Hexlet!"); > > 

Скомпилируем его. Компилятор javac вызывается так:

javac выполняет компиляцию, во время которой проверяется корректность программы (соответствие типов) и формируется файл HelloWorld.class с байткодом. После того как компиляция завершилась, программу можно запустить:

Как из .java сделать .class?

Я декомпилировал плагин в одной игре, изменил в нем пару слов и он стал формата .java. Как мне его скомпилировать обратно в формат .class?

Отслеживать
51.6k 201 201 золотой знак 63 63 серебряных знака 245 245 бронзовых знаков
задан 4 апр 2019 в 11:57
Over_Ghost Over_Ghost
11 1 1 серебряный знак 2 2 бронзовых знака
4 апр 2019 в 12:07

Не работает( пишу C:\Program Files\Java\jdk-12\bin\Levels.java ) мне пишет error: invalid flag: C:\Program Usage: javac use —help for a list of possible options пишу javac Levels.java и так же

4 апр 2019 в 12:38
Блин, я не знаю как там там у вас в полуконсоле на винде это делать. Попробуйте открыть —help
4 апр 2019 в 12:46

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

java — это файл, в нем может быть написано что угодно.
class — это скомпилированный файл.

Для компиляции используйте IDE. Если нет таковой — установите jdk нужной версии. Затем, если файл у вас один, используйте:

Отслеживать
ответ дан 4 апр 2019 в 12:59
michael_best michael_best
1,541 1 1 золотой знак 9 9 серебряных знаков 22 22 бронзовых знака
javac: file not found: Levels.java Usage: javac use -help for a list of possible options
4 апр 2019 в 13:18
@Over_Ghost Нужно указывать правильный путь до файла, а не просто написать его имя.
4 апр 2019 в 13:23

C:\Users\Admin\Desktop\Levels.java:93: error: package Main does not exist Main.econ.withdrawPlayer((OfflinePlayer)p, 100000.0); ^ C:\Users\Admin\Desktop\Levels.java:95: error: cannot find symbol final PermissionUser pm = PermissionsEx.getUser(p); ^ symbol: class PermissionUser location: class Levels 100 errors Получилось после javac C:\Users\Admin\Desktop\Levels.java До ошибок плевать главное где этот файл сохранился? 😀

Компилирование и исполнение Java-кода в Runtime

Привет Хабр! Сегодня я хотел бы поговорить про динамическое компилирование и исполнение Java-кода, подобно скриптовым языкам программирования. В этой статье вы найдете пошаговое руководство как скомпилировать Java в Bytecode и загрузить новые классы в ClassLoader на лету.

Зачем?

В разработке все чаще возникают типовые задачи, которые можно было бы закрыть простой генерацией кода. Например, сгенерировать DTO классы по имеющейся спецификации по стандартам OpenAPI или AsyncAPI. В целом, для генерации кода нет необходимости компилировать и выполнять код в runtime, ведь можно сгенерировать исходники классов, а собрать уже вместе с проектом. Однако при написании инструментов для генерации кода, было бы не плохо покрыть это тестами. А при проверке самый очевидный сценарий: сгенерировал-скомпилировал-загрузил-проверил-удалил. И вот тут-то и возникает задача генерации и проверки кода «на лету».

Также иногда возникают потребности выполнять какой-то код удаленно. Как правило это какие-то распределенные облачные вычисления. В этом случае можно отправлять исходный код на вычислительный узел, а там уже происходит динамическая сборка и выполнение.

Последовательность действий

Для выполнения Java-кода в Runtime нам потребуется:

  1. Динамически создать и сохранить наш код в .java файл.
  2. Скомпилировать исходники в Bytecode (файлы .class).
  3. Загрузить скомпилированные классы в ClassLoader.
  4. Использовать reflection api для получения методов и выполнения их.

Шаг 1. Генерация кода

Вообще для генерации исходников можно конечно просто написать текст через StringBuider в файл и быть довольным. Но мне хотелось бы показать более прикладные решения, поэтому рассмотрим вариант генерации кода с использованием пакета com.sun.codemodel, а вот тут есть неплохой туториал по этому пакету. Так же на его основе есть библиотека jsonschema2pojo для генерации кода на основе jsonschema. Итак к коду:

public void generateTestClass() throws JClassAlreadyExistsException, IOException < //создаем модель, это своего рода корень вашего дерева кода JCodeModel codeModel = new JCodeModel(); //определяем наш класс Habr в пакете hello JDefinedClass testClass = codeModel._class("hello.Habr"); // определяем метод helloHabr JMethod method = testClass.method(JMod.PUBLIC + JMod.STATIC, codeModel.VOID, "helloHabr"); // в теле метода выводим строку "Hello Habr!" method.body().directStatement("System.out.println(\"Hello Habr!\");"); //собираем модель и пишем пакеты в currentDirectory codeModel.build(Paths.get(".").toAbsolutePath().toFile()); >

Пример выше сгенерирует класс Habr.java с одним методом:

package hello; public class Habr < public static void helloHabr() < System.out.println("Hello Habr!"); >>

Шаг 2. Компиляция кода

Для компиляции в Bytecode обычно используется javac и выполняется он простой командой:

javac -sourcepath src -d build\classes hello\Habr.java

Однако, нам надо скомпилировать наш класс прямо из кода. И для этого есть библиотека компилятора, до которой можно достучаться через javax/tools/JavaCompiler. Это реализация javax/tools/Tool (которая лежит в /lib/tools.jar). Выглядеть это будет как-то так:

Path srcPath = Paths.get("hello"); List files = Files.list(srcPath) .map(Path::toFile) .collect(Collectors.toList()); //получаем компилятор JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //получаем новый инстанс fileManager для нашего компилятора try(StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) < //получаем список всех файлов описывающих исходники IterablejavaFiles = fileManager.getJavaFileObjectsFromFiles(files); DiagnosticCollector diagnostics = new DiagnosticCollector<>(); //заводим задачу на компиляцию JavaCompiler.CompilationTask task = compiler.getTask( null, fileManager, diagnostics, null, null, javaFiles ); //выполняем задачу task.call(); //выводим ошибки, возникшие в процессе компиляции for (Diagnostic diagnostic : diagnostics.getDiagnostics()) < System.out.format("Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource()); >>

Шаг 3. Загрузка и выполнение кода

Для выполнения кода нам надо загрузить его через ClassLoader и через reflection api вызвать наш метод.

//получаем ClassLoader, лучше получать лоадер от текущего класса, //я сделал от System только чтоб пример был рабочий ClassLoader classLoader = System.class.getClassLoader(); //получаем путь до нашей папки со сгенерированным кодом URLClassLoader urlClassLoader = new URLClassLoader( new URL[], classLoader); //загружаем наш класс Class helloHabrClass = urlClassLoader.loadClass("hello.Habr"); //находим и вызываем метод helloHabr Method methodHelloHabr = helloHabrClass.getMethod("helloHabr"); //в параметре передается ссылка на экземпляр класса для вызова метода //либо null при вызове статического метода methodHelloHabr.invoke(null);

Итог

В этой статье я постарался показать полноценный сценарий генерации и выполнения кода в Runtime. Самому мне это пригодилось при написании unit-тестов для библиотеки по генерации DTO классов на базе документации сгенерированной библиотекой springwolf. Реализацию тестов в моем проекте можно посмотреть тут.

Как скомпилировать java в class

Статья помогла понять самые основы, что происходит при сборке программы (и почему у меня постоянно ломалось). Но! Мне как новичку пришлось гуглить ещё 100500 статей как с JavaRush так и с других сайтов, чтобы выполнить инструкции по компиляции и сборке через Maven (Ant и Gradle не пробовала). Основные замечания: 1) Здесь опечатка в команде java -classpath ./bin BoxMachine. Правильно указать, что выполняется пакет : java -classpath ./bin src.BoxMachine 2) Не хватает краткого прямого указания, в каком редакторе можно составлять и редактировать файлы (тот же NotePad, я вообще делала в терминальном редакторе nano) — вроде бы и понятно, но все-таки. Для полноты текста и возможно у автора будет для новичков полезный совет. 3) В каком редакторе можно посмотреть байт-код? Для образовательных целей. Раз залезаем под капот и разбираем по кирпичикам, то почему бы и нет? Jetbrains декомпилирует обратно и это уже не так интересно 4) ! Для выполнения инструкций в этой статье (чтобы по чесноку, без IDE) Ant, Maven, Gradle должны устанавливаться и настраиваться отдельно. Не хватает хотя бы прямого указания на этот факт и ссылки на статью с инструкцией установки 5) pom.xml, который предлагает статья — неполный. Вот совсем. Мне пришлось добавлять properties и то проект скомпилировался, но правильно в jar не собрался.

5 сентября 2022

Доброго времени суток, комрады! Возник вопрос выполнение программы происходит через следующую команду: «java hello.java», Когда пишу «java hello», получаю сообщение «Error: Could not find or load main class hello» «Caused by: java.lang.ClassNotFoundException: hello»

3 сентября 2022

Почему-то IDE IntelliJ при выполнении пишет java -javaagent . «. App» типа того что-то и всё у него выходит хорошо в IDE, а вот вручную когда в командной строке наберёшь %JAVA_HOME%java «. App» не выполняет, пишет не может main класс выполнить. Может кто ни будь объяснить?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *