简体   繁体   English

如何使用 Maven 将 Clojure 依赖项包含到 Java 项目中

[英]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

Update更新

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

Update 2更新 2

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>

Intro介绍

I have a working demo for you using lein to build.我有一个使用lein构建的工作演示。 For the Maven part, the example project at the end.对于 Maven 部分,示例项目在最后。


Using lein to build使用lein构建

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

Update更新

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>

Update #2更新#2

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM