简体   繁体   中英

calling clojure from Java (Clojure Interop)

Calling Java from Clojoure is quite simple and straightforward but the inverse has proven to be unpredictable.

They seem to be two ways of doing it:

1)the following classes

 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.

I have opted for the 2nd option as it's more straight forward.

Here is the clojure code

(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.

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);" 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.

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. It's when I try implement it in the Azure functions.

Please see this question for a running example:

How to invoke Clojure function directly from Java

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.

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
  2. maven-shade-plugin

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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