[英]How to include Clojure dependencies to a Java project with Maven
I'm very new to all things JVM and want to start a Java project that involves a Clojure library as a dependency.我对 JVM 的所有事物都很陌生,并想启动一个 Java 项目,该项目涉及 Clojure 库作为依赖项。 I've seen this question on how to run Clojure code from Java, but when I try to run the jar file after
mvn package
, I get cannot find symbol
for variable Clojure
. I've seen this question on how to run Clojure code from Java, but when I try to run the jar file after
mvn package
, I get cannot find symbol
for variable Clojure
. My code looks like this so far:到目前为止,我的代码如下所示:
package org.example;
import clojure.java.api.Clojure;
import clojure.lang.IFn;
public class App
{
public static void main( String[] args )
{
IFn plus = Clojure.var("clojure.core", "+");
}
}
So far, my pom file looks like this:到目前为止,我的 pom 文件如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>project</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>poi</name>
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>clojars</id>
<url>https://repo.clojars.org/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>1.8.3</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.10.1</version>
</dependency>
<dependency>
<groupId>clj-python</groupId>
<artifactId>libpython-clj</artifactId>
<version>1.45</version>
</dependency>
</dependencies>
</project>
The clojure-maven-plugin
seemed to download the dependencies (I watched the usual downloads fly up the screen), but still no luck on invoking Clojure
after an import. clojure-maven-plugin
似乎下载了依赖项(我看着通常的下载在屏幕上飞舞),但在导入后调用Clojure
仍然没有运气。
Ultimately, I hope to be able to reference libpython-clj
from within Java.最终,我希望能够从 Java 中引用
libpython-clj
。
I tried Alan Thompson's answer and needed to run lein pom
to get a pom.xml file.我尝试了 Alan Thompson 的回答,需要运行
lein pom
来获取 pom.xml 文件。 Then I needed to add the following to the pom at the project level to get it to mvn -q compile <properties> <maven.compiler.source>1.6</maven.compiler.source> <maven.compiler.target>1.6</maven.compiler.target> </properties>
然后我需要在项目级别将以下内容添加到 pom 以使其 mvn -q compile
<properties> <maven.compiler.source>1.6</maven.compiler.source> <maven.compiler.target>1.6</maven.compiler.target> </properties>
However, at mvn -q exec
gives me long stack trace ending with然而,在
mvn -q exec
给了我很长的堆栈跟踪,以
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:java (default-cli) on project demo: An exception occured while executing the Java class. example.Main -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:java (default-cli) on project demo: An exception occured while executing the Java class. example.Main
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: An exception occured while executing the Java class. example.Main
at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:311)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
... 19 more
Caused by: java.lang.ClassNotFoundException: example.Main
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:246)
at java.base/java.lang.Thread.run(Thread.java:834)
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
It seems running mvn clean install && java -jar target/<whatever-it's called>.jar
works when you add the following snippet to the pom.xml within the <plugins>
section.似乎运行
mvn clean install && java -jar target/<whatever-it's called>.jar
将以下代码段添加到 pom.Z0F635D0E0F3874FFF8B581C132E 部分中的<plugins>
.6777
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>demo.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
I have a working demo for you using lein
to build.我有一个使用
lein
构建的工作演示。 For the Maven part, the example project at the end.对于 Maven 部分,示例项目在最后。
lein
to buildlein
构建Files:文件:
~/expr/demo > ls -ldF **/*.{java,clj}
-rwxr-xr-x 1 alanthompson staff 904 Jul 24 13:25 project.clj*
-rw-r--r-- 1 alanthompson staff 130 Jul 24 13:24 src/clj/demo/core.clj
-rw-r--r-- 1 alanthompson staff 373 Jul 24 13:17 src/java/demo/Main.java
-rw-r--r-- 1 alanthompson staff 129 Jul 24 13:20 test/clj/tst/demo/core.clj
project.clj项目.clj
(defproject demo "0.1.0-SNAPSHOT"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.10.2-alpha1"]
[prismatic/schema "1.1.12"]
[tupelo "20.07.01"]]
:profiles {:uberjar {:aot :all}}
:global-vars {*warn-on-reflection* false}
:main demo.core ; when use ^:skip-aot ???
:source-paths ["src/clj"]
:java-source-paths ["src/java"]
:test-paths ["test/clj"]
:target-path "target/%s"
:compile-path "%s/class-files"
:clean-targets [:target-path]
:jvm-opts ["-Xms500m" "-Xmx4g" ]
)
Java source Java源
package demo;
import clojure.java.api.*;
import clojure.lang.IFn;
public class Main {
public static double add2(double x, double y) {
return (x + y);
}
public static void main(String[] args) {
System.out.println("java main - enter");
IFn plus = Clojure.var("clojure.core", "+");
plus.invoke(1, 2);
System.out.println("java main - leave");
}
}
Clojure main Clojure 主
(ns demo.core
(:use tupelo.core)
(:gen-class))
(defn -main [& args]
(println :clj-main-enter)
(println :clj-main-leave))
Clojure test Clojure 测试
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:import [demo Main])
(:gen-class))
(dotest
(spyx (Main/add2 2 3)))
The Clojure part is straightforward using lein: Clojure 部分使用 lein 很简单:
~/expr/demo > lein clean; lein run
:clj-main-enter
:clj-main-leave
~/expr/demo > lein test
------------------------------------------
Clojure 1.10.2-alpha1 Java 14.0.1
------------------------------------------
lein test tst.demo.core
(Main/add2 2 3) => 5.0
Ran 2 tests containing 0 assertions.
0 failures, 0 errors.
We will use lein to build the uberjar:我们将使用 lein 来构建 uberjar:
~/expr/demo > lein uberjar
Compiling demo.core
Created /Users/alanthompson/expr/demo/target/uberjar/demo-0.1.0-SNAPSHOT.jar
Created /Users/alanthompson/expr/demo/target/uberjar/demo-0.1.0-SNAPSHOT-standalone.jar
then run either Clojure main using java -jar
or Java main using java -cp
然后运行 Clojure main 使用
java -jar
或 Java main 使用java -cp
# Entrypoint controlled by `:main` key in `project.clj` => clojure `demo.main/-main` function
~/expr/demo > java -jar /Users/alanthompson/expr/demo/target/uberjar/demo-0.1.0-SNAPSHOT-standalone.jar
:clj-main-enter
:clj-main-leave
# ***** notice `demo.Main` Java class name *****
~/expr/demo > java \
-cp /Users/alanthompson/expr/demo/target/uberjar/demo-0.1.0-SNAPSHOT-standalone.jar \
demo.Main
java main - enter
java main - leave
Just tried Stuart Halloway's Clojure Maven example .刚刚尝试了 Stuart Halloway 的Clojure Maven 示例。
It will crash with Java 14 , so beware!它将与 Java 14 一起崩溃,所以要小心!
Results:结果:
~/expr/demo/clojure-from-java > java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.252-b09, mixed mode)
~/expr/demo/clojure-from-java > mvn -q clean
~/expr/demo/clojure-from-java > mvn -q compile
~/expr/demo/clojure-from-java > mvn -q exec:java -Dexec.mainClass=example.Main
fn says hello
file filter returns false
object toString returns <object created Fri Jul 24 13:55:11 PDT 2020>
You can fix the problem with Java 14 if you update the pom.xml
to output Java 1.8 features. You can fix the problem with Java 14 if you update the
pom.xml
to output Java 1.8 features. Excerpt:摘抄:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- put your configurations here -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<sourceDirectory>src/java</sourceDirectory>
<resources>
<resource>
<directory>src/clojure</directory>
</resource>
</resources>
</build>
The part that matters is adding 1.8
here:重要的部分是在此处添加
1.8
:
<source>1.8</source>
<target>1.8</target>
Enjoy!享受!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.