简体   繁体   English

从 Java 调用 clojure (Clojure Interop)

[英]calling clojure from Java (Clojure Interop)

Calling Java from Clojoure is quite simple and straightforward but the inverse has proven to be unpredictable.从 Clojoure 调用 Java 非常简单直接,但事实证明,反过来却是不可预测的。

They seem to be two ways of doing it:他们似乎有两种方法:

1)the following classes 1)以下课程

 i) import clojure.java.api.Clojure; , ii) import clojure.lang.IFn;

2)compile your clojure into an uberjar then import it into the java code. 2)将你的clojure编译成一个uberjar,然后将它导入到java代码中。

I have opted for the 2nd option as it's more straight forward.我选择了第二个选项,因为它更直接。

Here is the clojure code这是clojure代码

(ns com.test.app.service
 (:gen-class
       :name com.test.app.service
       :main false
       :methods [^{:static true} [returned [int] int]]))

    (defn returned
      [number]
      (* 2 number))

    (defn -returned
      [number]
      (returned number))

Here is the Java code.这是Java代码。

package com.s.profile;

import java.util.*;
import com.microsoft.azure.serverless.functions.annotation.*;
import com.microsoft.azure.serverless.functions.*;
import com.test.app.service;


/**
 * Azure Functions with HTTP Trigger.
 */
public class Function {
    /**
     * This function listens at endpoint "/api/hello". Two ways to invoke it using "curl" command in bash:
     * 1. curl -d "HTTP Body" {your host}/api/hello
     * 2. curl {your host}/api/hello?name=HTTP%20Query
     */
    @FunctionName("hello")
    public HttpResponseMessage<String> hello(
            @HttpTrigger(name = "req", methods = {"get", "post"}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        // Parse query parameter
        String query = request.getQueryParameters().get("name");
        String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponse(400, "Please pass a name on the query string or in the request body");
        } else {
            service.returned(4);
            context.getLogger().info("process data" );
            return request.createResponse(200, "Hellos, " + name );
        }
    }
}

When ever I make the "service.returned(4);"每当我制作“service.returned(4);” the system never returns.系统永远不会返回。 I can't quite figure out why to me it comes off like the function doesn't return from Clojure but I can't see the cause.我不太明白为什么对我来说它会像函数没有从 Clojure 返回一样消失,但我看不到原因。

Just to add some context I have tried it when its a simple hello world java app which just prints out the result and it works.只是为了添加一些上下文,当它是一个简单的 hello world java 应用程序时,我已经尝试过它,它只是打印出结果并且它可以工作。 It's when I try implement it in the Azure functions.当我尝试在 Azure 函数中实现它时。

Please see this question for a running example:请参阅此问题以获取运行示例:

How to invoke Clojure function directly from Java 如何直接从 Java 调用 Clojure 函数

I would suggest simplifying your code at first, then adding back in the Azure stuff one line at a time in case some interaction there is causing the problem.我建议首先简化您的代码,然后在 Azure 内容中一次添加一行,以防某些交互导致问题。

I followed these instructions and it seemed to resolve the error of class not found.我遵循了这些说明,它似乎解决了找不到类的错误。 It seems as though when running the command好像在运行命令时

mvn azure-functions:run

It doesn't automatically find all imported libraries.它不会自动找到所有导入的库。 You either have to use你要么必须使用

  1. maven-assembly-plugin Maven 程序集插件
  2. maven-shade-plugin行家阴影插件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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