Программно скомпилировать класс Java в пакете, хранящемся в произвольной подпапке - PullRequest
0 голосов
/ 03 февраля 2010

Я хочу скомпилировать приложение на Java, состоящее из различного количества классов Java в определенном количестве пакетов.В командной строке я могу перейти в папку, содержащую корневой пакет, и набрать:

javac rootpackage/subpackage/*.java

или

javac rootpackage/*/*.java

, чтобы скомпилировать все классы Java во всех основных подпакетах моегоrootpackage.

Однако я хотел бы иметь возможность сделать это в приложении Java.(Идея заключается в том, что мы предоставляем студентам приложение, содержащее модульные тесты. Для выполнения модульных тестов необходимо выполнить их код, затем приложение создает файл JAR, содержащий их исходные файлы, которые были «помечены водяными знаками» с результатами теста. Всеэто работает нормально, но мы хотели бы убедиться, что проверенные файлы классов созданы из представленных исходных файлов, поэтому возникает идея программной компиляции исходных файлов Java).

Проблема заключается в том, что каждый студент хранит своикорневой пакет в произвольной позиции, и я не могу передать местоположение файла JavaCompiler (javax.tools).

Возможно ли это, и если да, может кто-нибудь дать несколько советов о том, как получитьпроизвольно размещенный корневой пакет, скомпилированный правильно.

Приветствия

Ричард

Подробнее:

студент имеет структуру папок:

/home/student/work/java/myproject/

, который содержит корневой пакет.Они запускают приложение (возможно, хранящееся в этой папке - и, таким образом, никаких проблем, но, скорее всего, хранящееся в другом месте), которое запрашивает у них папку, содержащую корневой пакет.После ввода студенты нажимают кнопку создания JAR, которая компилирует файлы в свои пакеты, запускает тесты для вновь скомпилированных файлов и затем создает JAR.

Обдумывая эту проблему, возможно, что решение состоит в том, чтобы попросить студентов установить наше приложение 'create JAR' в папку, содержащую их корневой пакет.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2010

Последний аргумент JavaCompiler.getTask () - это Iterable <? расширяет JavaFileObject>, содержащий модули компиляции для передачи компилятору. Одной из предоставленных реализаций JavaFileObject является SimpleFileJavaObject (http://java.sun.com/javase/6/docs/api/javax/tools/SimpleJavaFileObject.html).. Он создан с помощью объекта java.net.URI, который может быть легко создан из объекта File. Собрав все это вместе, выполните что-то вроде этого:

List<JavaFileObject> javaFiles = new ArrayList<JavaFileObject>();
File javaFile = new File(rootPackageDirFromUser, fileNameInRootDir);
URI javaURI = javaFile.toURI();
javaFiles.add(new SimpleJavaFileObject(javaURI, JavaFileObject.Kind.SOURCE));
JavaCompiler.CompilationTask task =
    ToolProvider.getSystemJavaCompiler().getTask(..., javaFiles);

где rootPackageDirFromUser предоставляется пользователем, который сообщает вам, где хранятся файлы, а fileNameInRootDir - это имя исходного файла java в этом каталоге. Если вы заранее не знаете имен файлов, вам нужно будет перебрать rootPackageDirFromUser для создания списка.

Я не проверял это, но это должно дать вам общее представление.

0 голосов
/ 03 февраля 2010

Не могли бы вы заглянуть в начало каждого файла .java для начала строки:

package com.blah.blah.assignment;

т.е. найдите начало имени пакета и затем найдите первый каталог в вашем пути поиска, начинающийся с com (в этом примере), а затем укажите этот путь к объекту JavaCompiler, или я неправильно понял ваш вопрос?

Только что посмотрев на пакет javax.tools, почему бы не создать составную оболочку для javaFilemanager, который оборачивает ForwardingjavaFileManager, который будет перенаправлять все запросы на методы, такие как getFileForInput или getJavaFileForInput, в соответствующий начальный каталог в исходной папке студента (в соответствии с вашим предварительным анализом первого файла .java для определения корня их исходного пути)

...