Home Java javaTutorial Calling Clojure from Java using a real example (Clojure Quarkus)

Calling Clojure from Java using a real example (Clojure Quarkus)

Oct 02, 2024 am 06:31 AM

Calling Clojure from Java using a real example (Clojure   Quarkus)

The challenge

Last weekend, I decided to explore more about how Clojure can interact with the existent Java ecosystem, the challenge was simple:

Create a simple web framework in Clojure using the Quarkus framework as a base.

Premises:

  • The Quarkus does not know what will be executed by route, even not how many routes exist.
  • I should be able to create routes and handlers using Clojure as simply as possible:
(defn send-hello-world [] "Hello World")

(defn routes [] [{:method "GET"
                  :path "/hello" 
                  :handler send-hello-world}])
Copy after login

Some definitions:

  • Quarkus: Quarkus is a full-stack, Kubernetes-native Java framework made for Java virtual machines (JVMs) and native compilation, optimizing Java specifically for containers.
  • Clojure: Is a dynamic, general-purpose programming language

Step 1: Creating a Quarkus app

It is very easy to start an app in Quarkus you can follow this tutorial, as you can see your last command will be quarkus create && cd code-with-quarkus after that you can open the folder code-with-quarkus with your favorite IDE, the command created the basic structure of a Quarkus app, and you can run with quarkus dev

Step 2: Enable the project to recognize clj files

You need to configure Quarkus to include .clj files in target folder (The folder with your compiled app), and you can do it by adding this configuration in pom.xml inside

<resources>
        <resource>
            <directory>/</directory>
            <includes>
                <include>*.clj</include>
            </includes>
        </resource>
    </resources>
Copy after login

Step 3: Create Clojure file

As I mentioned earlier, I defined one structure to declare my routes, in the same location of the folder main. Then I created a folder named quarkus_clj with a file called core with the code below:

(ns quarkus-clj.core)

(defn send-hello-world [] "Hello World")

(defn routes [] [{:method "GET"
                  :path "/hello" 
                  :handler send-hello-world}])
Copy after login

Step 4: Enabling Quarkus to handle my Clojure program

Here is where the magic happens ??!

First of all, you should install the Clojure inside your Quarkus app; you can do it by adding a dependency in pom.xml

<dependency>
      <groupId>org.clojure</groupId>
        <artifactId>clojure</artifactId>
        <version>1.11.1</version> 
</dependency>
Copy after login

Now, you can delete the file GreetingResource.java and its tests. In the same place, create a file Starting.java

I write some comments explaining how it works

@ApplicationScoped
public class Starting {
    //Setup app routes
    public void setupRouter(@Observes Router router) {
        // Load Clojure core;
        IFn require = Clojure.var("clojure.core", "require");
        // Load quarkus-clj.core namespace
        require.invoke(Clojure.read("quarkus-clj.core")); 

        // Load the route list function
        IFn routesFn = Clojure.var("quarkus-clj.core", "route");

        // Invoke the function with no parameters
        PersistentVector routesVector = (PersistentVector) routesFn.invoke();

        //For each route in routes vector 
        for (Object route : routesVector) {
            /**Get the route map, example
            {:method "GET"
             :path "/hello" 
             :handler send-hello-world}
             */
            PersistentArrayMap routeMap = (PersistentArrayMap) route;

            //Get :path value
            String path = (String) routeMap.valAt(Clojure.read(":path"));
            //Get :handler function
            IFn handlerRoute = (IFn) routeMap.valAt(Clojure.read(":handler"));
            //Get :method value
            String method = (String) routeMap.valAt(Clojure.read(":method"));
            //Create a handler to exec handler function
            Handler<RoutingContext> handlerFn = (RoutingContext context) -> {
            String result = (String) handlerRoute.invoke();  
            context.response().end(result);
        };
            //Config the route in quarkus
            router.route(HttpMethod.valueOf(method), path).handler(handlerFn);
        }
    }
}
Copy after login

Now you can just run: quarkus dev open your declared route and see the result!

Conclusion

This was a quick example of how to use Clojure inside a Quarkus app to create dynamic routes. With just a few steps, we connected the two ecosystems and set up a basic routing system. Feel free to expand on this foundation and explore other possibilities with Clojure and Quarkus!

The above is the detailed content of Calling Clojure from Java using a real example (Clojure Quarkus). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Apr 19, 2025 pm 04:51 PM

Troubleshooting and solutions to the company's security software that causes some applications to not function properly. Many companies will deploy security software in order to ensure internal network security. ...

How to simplify field mapping issues in system docking using MapStruct? How to simplify field mapping issues in system docking using MapStruct? Apr 19, 2025 pm 06:21 PM

Field mapping processing in system docking often encounters a difficult problem when performing system docking: how to effectively map the interface fields of system A...

How to elegantly obtain entity class variable names to build database query conditions? How to elegantly obtain entity class variable names to build database query conditions? Apr 19, 2025 pm 11:42 PM

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

How do I convert names to numbers to implement sorting and maintain consistency in groups? How do I convert names to numbers to implement sorting and maintain consistency in groups? Apr 19, 2025 pm 11:30 PM

Solutions to convert names to numbers to implement sorting In many application scenarios, users may need to sort in groups, especially in one...

How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? Apr 19, 2025 pm 11:45 PM

Start Spring using IntelliJIDEAUltimate version...

How to safely convert Java objects to arrays? How to safely convert Java objects to arrays? Apr 19, 2025 pm 11:33 PM

Conversion of Java Objects and Arrays: In-depth discussion of the risks and correct methods of cast type conversion Many Java beginners will encounter the conversion of an object into an array...

How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? Apr 19, 2025 pm 09:51 PM

When using TKMyBatis for database queries, how to gracefully get entity class variable names to build query conditions is a common problem. This article will pin...

E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? Apr 19, 2025 pm 11:27 PM

Detailed explanation of the design of SKU and SPU tables on e-commerce platforms This article will discuss the database design issues of SKU and SPU in e-commerce platforms, especially how to deal with user-defined sales...

See all articles