Clojure и Java-взаимодействие в реальном мире

Я подумываю начать использовать (не играя) Clojure. Есть ли полезные справочники? Я не спрашиваю о lein, javac или каких-либо других "маленьких" ручных инструментах. Мне нужно знать, как иметь Java и Clojure источники в eclipse в том же проекте. Как заставить их звонить друг другу без ошибок компиляции? Как настроить maven? Как создать полноценную среду разработки? Возможно ли это на данный момент? Какие плагины могут быть полезны? С чего начать?

Ответ 1

У меня есть полностью работающая производственная установка с Eclipse, Maven и Clojure, которая работает очень хорошо на данный момент. Надеюсь, это полезно в качестве примера хорошей настройки многоугольника в Java IDE.

Я не использую leiningen - ничего против lein вообще - он очень хороший и идеальный в чистом мире Clojure/CLI. Но я обнаружил, что чистый Maven лучше работать в среде Polyglot Java + Clojure с IDE, поскольку интеграция инструментов намного лучше. Также с точки зрения экосистемы/аудитории/сообщества, если вы хотите, чтобы люди из мира Java могли создавать свой источник, вы будете вызывать гораздо меньше путаницы, если просто используете Maven напрямую.

Вот моя настройка:

  • Eclipse 4.2 как основная IDE
  • Counterclockwise Плагин Eclipse - очень хороший, позаботится об REPL, Clojure и т.д.
  • Maven используется для управления всеми проектами (я использую встроенную интеграцию Eclipse Maven в основном, но иногда также использую версию CLI).
  • cljunit, используемый для включения тестов JUnit в Clojure части проекта
  • Github/Travis CI используется для SCM и непрерывной интеграции, доступ к которому осуществляется с помощью встроенного провайдера EGit в Eclipse

С точки зрения того, как я сам управляю/настраиваю сам проект:

  • Я настраиваю все с помощью Maven, используя стандартный макет каталога Maven. Polyglot Java + Clojure Проекты обычно имеют как src/main/java, так и src/main/clojure
  • Clojure - это просто зависимость от Maven, как и любая другая библиотека Java.
  • Я создаю исходные каталоги Clojure в каталогах ресурсов в настройке Maven. Это означает, что файлы .clj попадают в любые банки и могут быть загружены/выполняться динамически во время выполнения.
  • Обычно я делаю точку входа на стороне Java с помощью public static void main(...), как обычно, но довольно быстро вызываю код Clojure. См. Это сообщение в блоге вызов Clojure из Java.

Наконец, некоторые советы по кодированию для polyglot Java + Clojure

  • Я нахожу, что Java лучше подходит для низкоуровневых структур данных, библиотек и алгоритмов, а Clojure лучше интегрирует вещи вместе и "клей".
  • Clojure вызов Java обычно проще/элегантнее, чем наоборот. Также это имеет смысл, поскольку вы обычно хотите, чтобы зависимости проходили таким образом (код более высокого уровня, вызывающий код нижнего уровня).
  • Если вы сделаете все свои классы Java неизменяемыми, они будут очень хорошо играть в мире Clojure с минимальными усилиями.
  • Иногда стоит сделать один или несколько ваших классов Java реализованными некоторыми интерфейсами Clojure, особенно clojure.lang.IFn, например. Таким образом, ваши объекты Java могут действовать как функции первого класса в коде Clojure.

Вот пример проекта, который смешивает Java и Clojure source:

Я также написал небольшую библиотеку (clojure-utils), которая включает в себя пример кода для вызова Clojure с Java, который вы можете найти полезно.

Ответ 2

Несмотря на ваш тон о leiningen, я рекомендую посмотреть на него. Leiningen поддерживает компиляцию Java, поэтому объединение источников java и clojure в одном проекте не является проблемой.

Плагин Counterclockwise, плагин clojure для Eclipse, может работать с файлами проекта leiningen (project.clj). Таким образом, в Eclipse у вас есть управление зависимостями и компиляция java, которые обрабатываются для вас, определяя правильные вещи в project.clj, без необходимости отдельно устанавливать leiningen или выполнять команды из командной строки.

В project.clj установите : java-source-paths, например, например:

:java-source-paths ["src/main/java"] 

В пакете src/main/java добавлен класс Foo:

package main.java;

public class Foo {
    public static final String value = "Michiel";
}

Где-то в исходном файле clojure определите эту функцию, и "Мичиэль" будет напечатан, когда он вызывается:

(defn foo
  "I don't do a whole lot."
  []
  (println (main.Foo/value)))

Дальнейшее чтение:

Ответ 3

Вы также можете попробовать фреймворк "Funky". Он полностью разделит вас на Clojure и Java-код. Просто посмотрите https://github.com/windler/Funky