2014-11-03 3 views
1

Я хотел бы:Построения баночки проекта Фрега с использованием Gradle

  1. использовать язык программирования Фреге написать простой «Hello World» кусок кода,
  2. затем с помощью компилятору Фрега, порождающим эквивалентный исходный код Java,
  3. , а затем создание исполняемого файла Jar для запуска из командной строки,
  4. все предыдущие шаги должны быть «контролируемы» Gradle.

Я могу сгенерировать исходный код (элементы 1 и 2. из предыдущего списка), но я не могу указать структуру пакета исходного кода Java на выходе, то есть я могу не видеть инструкцию Java package как первую строку кода в генерации исходного кода Java. Я могу указать компилятор Фреге, куда поместить сгенерированный код (через аргумент -d).

Я думаю, что это причина, почему при создании исполняемого Jar, а затем его запуск, я вижу похожие ошибки (в соответствии с различными попытками задач Gradle), например: no main manifest attribute.

Фрег исходный код сохраняется в файл с именем HelloFrege.fr, сгенерированный исходный код Java в файл с именем HelloFrege.java (я проверил файл содержит ожидаемый main метода).

Здесь есть версия Gradle "Jar задачи":

//create a single Jar with all dependencies 
task fatJar(type: Jar) { 
    manifest { 
     attributes 'Implementation-Title': 'Hello Frege Jar Example', 
        'Implementation-Version': version, 
        'Main-Class': 'HelloFrege' 
    } 
    baseName = project.name + '-all' 
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    with jar 
} 

Здесь есть еще одна версия "Жар" задачи Gradle:

jar { 
    manifest { 
     attributes 'Main-Class': 'HelloFrege' 
    } 
} 

Как я могу решить эту проблему? Я хотел бы избежать, чтобы вручную добавить ссылку на пакет для автоматически созданного файла исходного кода Java.

ответ

2

Если ваше имя модуля в Frege не имеет значения, например HelloWorld, вы не увидите оператор пакета, сгенерированный на Java. Имя модуля станет именем класса, и пакет будет пустым или по умолчанию.

Если ваше имя модуля квалифицировано как foo.bar.HelloWorld, то foo.bar будет именем пакета, а HelloWorld будет именем класса в сгенерированном источнике Java.

Правило состоит в том, что последней частью имени модуля становится имя класса, а квалификаторы образуют имя пакета в сгенерированном источнике Java.

1

Я не уверен, что Gradle может сделать для вас в этом отношении, но без Gradle, следующее должно быть как минимум:

... build your jar, as before ... 
jar -uvfe project-all.jar HelloFrege 
java -jar project-all.jar # run it 

Это, конечно, это просто еще один способ создать манифест , Если это сработает, тогда пришло время исследовать, почему град отказывается это делать.

Postscriptum: Подумав еще минуту о том, что может быть проблемой, мне кажется, что вы можете думать, что имя/путь исходного файла имеет какое-либо отношение к имени пакета java. Это не так в Frege, хотя хорошая практика заключается в том, чтобы путь к файлу соответствовал имени пакета, а базовое имя файла соответствовало имени класса (как и в Java).Кроме того, чтобы устранить некоторую путаницу, используйте модуль ключевое слово в frege. Как объяснил Marimuthu, пакет Java и имя класса получают из имени модуля frege.

Пример:

$ cat Foo.fr 
module my.org.Baz where 
... 
$ java -jar fregec.jar -d bin Foo.fr 

Это создает Baz класс в пакете my.org, и создает файл класса в bin/my/org/Baz.class

0

Я отправляю здесь мои выводы до сих пор. Комбинация команд Gradle, которая работает для меня следующий один (вызов его из командной строки, набрав gradle clean generateJavaSrcFromFregeSrc fatJar):

task generateJavaSrcFromFregeSrc { 
    ant.java(jar:"lib/frege3.21.586-g026e8d7.jar",fork:true) { 
    arg(value: "-j") // do not run the java compiler 
    arg(value: "-d") 
    arg(value: "src/main/java") // the place where to put the generated source code (paired to the -d argument) 
    arg(value: "src/main/frege/HelloFrege.fr") 
    } 
} 

jar { 
    manifest { 
     attributes 'Main-Class': 'org.wathever.HelloFrege' 
    } 
} 

task fatJar(type: Jar) { 
    from files(sourceSets.main.output.classesDir) 
    from files(sourceSets.main.output.resourcesDir) 
    //from {configurations.compile.collect {zipTree(it)}} // this does not include the autogenerated source code 
    baseName = project.name + '-fatJar' 
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    with jar 
} 
  • манифеста детали должны быть указаны в jar блоке кода, если я указываю их в task fatJar, то при запуске банки я получаю no main manifest attribute, in [...].
  • Если я использую только блок кода jar со свойством from("$projectDir") { include 'lib/**'} включить банку Фрега, то я получаю сообщение об ошибке, как java.lang.ClassNotFoundException (я думаю, потому что Jar включен, как это и не как набор .class файлов).
  • Папка src/main/java/org/wathever должна быть там перед запуском Gradle (дополнительная информация: Конвенция префикс Maven src/main/java с как суффикс «Java пакета», как указано внутри HelloFrege.fr исходного кода: module org.wathever.HelloFrege where)

Некоторые полезные данные Я нашел:

+0

Заметим, однако, что вы не можете использовать флаг -j в целом. Например, когда A зависит от B, тогда компилятору понадобится файл класса B при компиляции A. – Ingo

Смежные вопросы