{"id":13682386,"url":"https://github.com/jaju/spring-boost","last_synced_at":"2025-12-12T01:16:40.575Z","repository":{"id":48183398,"uuid":"323902400","full_name":"jaju/spring-boost","owner":"jaju","description":"Introduce Clojure and live-coding power to your Spring Boot application!","archived":false,"fork":false,"pushed_at":"2023-03-21T17:05:42.000Z","size":55,"stargazers_count":38,"open_issues_count":1,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-08-02T13:34:04.131Z","etag":null,"topics":["clojure","nrepl","reactive","springboot2","webflux"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaju.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-12-23T12:56:50.000Z","updated_at":"2024-07-08T18:12:52.000Z","dependencies_parsed_at":"2024-01-14T15:49:04.616Z","dependency_job_id":null,"html_url":"https://github.com/jaju/spring-boost","commit_stats":null,"previous_names":["jaju/spring-boot-bugger"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaju%2Fspring-boost","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaju%2Fspring-boost/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaju%2Fspring-boost/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaju%2Fspring-boost/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaju","download_url":"https://codeload.github.com/jaju/spring-boost/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224206042,"owners_count":17273378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","nrepl","reactive","springboot2","webflux"],"created_at":"2024-08-02T13:01:45.224Z","updated_at":"2025-10-22T02:13:24.302Z","avatar_url":"https://github.com/jaju.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"* What is spring-boost?\n\nEver wished to introduce Clojure into your SpringBoot app (organization)?\nAnd, want to start very small - ~nrepl~ and a ring-like sub-module - and then use REPL-power for live-coding and adding new functionality?\n\nThen, ~spring-boost~ simplifies it for you!\n\nA complete example of how it works can be found at [[https://github.com/jaju/spring-boost-example][jaju/spring-boost-example]].\n\n** Caveat\nFor the web-endpoints, the library assumes *Spring Webflux*. It will not work with standard, thread-ed spring-boot.\nBut ~nREPL~ will work just fine irrespective.\n\n* The Pitch: Sample Application Code\nHere's how you can write Clojure code, using *Compojure*, with Springboot.\nThe interface is _ring like_ - Mostly ring, but with a few quirks that should not matter for most common use-cases.\n\n** What will my Clojure look like?\nHere is an example code that you can use in your SpringBoot application!\nIt works along-side your existing Java code, without interfering, and you can access Clojure from your Java.\n\nThe following code shows\n1. Setting up end-points - routes and all - with Compojure\n2. Setting up a websocket handler - builds on top of Springboot's websocket infrastructure.\n\n#+begin_src clojure\n(ns org.msync.spring-clj.core\n  (:require [org.msync.spring-boost :as boost]\n            [compojure.core :refer :all]\n            [compojure.route :refer [not-found]]\n            [clojure.string])\n  (:import [java.util.logging Logger]\n           [org.springframework.context ApplicationContext]))\n\n(defonce logger (Logger/getLogger (str *ns*)))\n\n(defroutes app\n  \"Root hello-world GET endpoint, and another echo end-point that handles both GET and POST.\n  The :body entry in the request-map comes in either as a map for JSON requests, or as a String\n  for other types.\"\n  (GET \"/\" [:as {query-string :query-string}]\n       (str \"\u003ch1\u003eHello World.\u003c/h1\u003e\"\n            (if-not (clojure.string/blank? query-string) (str \"We received a query-string \" query-string))))\n  (GET \"/echo/:greeter\" [greeter]\n       {:status 200\n        :headers {:content-type \"application/json\"}\n        :body {:greeting (str \"Hello, \" greeter)}})\n  (POST \"/echo/:greeter\" [greeter :as request]\n        {:status 200\n         :headers {:content-type \"application/json\"}\n         :body {:greetings (str \"Hello, \" greeter)\n                :echo (:body request)}})\n  (not-found \"\u003ch1\u003ePage not found\u003c/h1\u003e\"))\n\n(defn web-socket-handler [session]\n  (pr-str session)\n  ;; Use the session as you wish - to create session-specific handlers\n  (fn [^String message]\n    (str \"Hello, \" (.toUpperCase message))))\n\n(defn main\n  \"Set this as your entry-point for the Clojure code in your spring-boot app.\n  Gets the ApplicationContext object as an argument - which you are free to ignore or use.\"\n  [^ApplicationContext application-context]\n\n  (.info logger (str \"[spring-clj] Initializing clojure app...\"))\n  (boost/set-handler! app)\n  (boost/set-websocket-handler! web-socket-handler))\n#+end_src\n\nNote that the paths are relative to the base path set in ~application.yml~. Hence, ~/echo/:greetings~ will be accessible at ~/clojure/echo/:greetings~.\n\n** Configure Gradle\n*** Modify ~build.gradle.kts~ (or, ~build.gradle~)\nThis is the Gradle-Kotlin version.\n#+begin_src kotlin\nrepositories {\n    maven {\n        name = \"Clojars\"\n        url = uri(\"https://clojars.org/repo\")\n    }\n}\n\ndependencies {\n    developmentOnly(\"org.msync:spring-boost:0.2.0-SNAPSHOT\")\n    developmentOnly(\"compojure:compojure:1.6.3\")\n}\n#+end_src\n*** Ensure your clojure code is copied to the classpath\nAssuming you will write your clojure code in ~src/main/clojure~\n\n#+begin_src kotlin\ntasks.register\u003cCopy\u003e(\"copyClojure\") {\n    into(\"build/classes/java/main\") {\n        destinationDir = file(\".\")\n        from(\"src/main/clojure\")\n    }\n}\n\ntasks.getByName(\"bootRun\").dependsOn(\"copyClojure\")\ntasks.getByName(\"bootJar\").dependsOn(\"copyClojure\")\n#+end_src\n\n** Hint Springboot using ~@ComponentScan~\n#+begin_src java\npackage com.company.my_application;\n\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.context.annotation.ComponentScan;\n\n@SpringBootApplication\n@ComponentScan(\"org.msync.spring_boost\")\n// And other standard stuff\npublic class YourApplication {\n    // Your code here\n}\n#+end_src\n\n** Modify ~application.yml~ (or ~application.properties~)\nBy default, port 7888 is used. But add ~clojure-component.nrepl-port~ to your ~application.yml~ (or equivalent) file as follows\n\n#+begin_src yaml\n# ...\nclojure-component:\n  nrepl-port: 8190\n  nrepl-start: true\n  root-path: /clojure\n  ws-path: /ws\n  init-symbol: org.msync.spring-clj.core/main\n# ...\n#+end_src\n\n** Run \"bootRun\"\n\nAnd, *run*!\n\n#+begin_src bash\n./gradlew bootRun\n#+end_src\n\nAnd you should see something like the following\n#+BEGIN_EXAMPLE\n...\n[2021-09-10 12:08:14,182] INFO  [main] org.msync.spring_boost.application_context$_component_init::invokeStatic Initializing the ClojureComponent\n[2021-09-10 12:08:14,984] INFO  [main] org.msync.spring_boost.Boost::startNrepl nREPL server started on port = 8190\n[2021-09-10 12:08:14,986] INFO  [main] org.msync.spring_boost.Boost::setupAppInit Initializing clojure code: org.msync.spring-clj.core/main\n[2021-09-10 12:08:21,097] INFO  [main] jdk.internal.reflect.NativeMethodAccessorImpl::invoke0 [spring-clj] Initializing clojure app...n\n...\n#+END_EXAMPLE\n\n* Connect to the NREPL\n\nStarting ~nREPL~ by default can be controlled via configuration. But you can easily start/stop ~nREPL~ using two exposed end-points, that take *POST* requests.\n\nFor your convenience, there's a namespace you can switch to and get hold of the ~ApplicationContext~ object via the /state/ atom's ~:ctx~ key.\n\n#+begin_src clojure\nuser\u003e @org.msync.spring-boost.application-context/state\n;; =\u003e\n{:ctx #object[org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext\n              0x333bd779\n              \"org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@333bd779, started on Wed Sep 01 21:47:28 IST 2021\"]}\n#+end_src\n\n\n** Control the NREPL server\n*** Start it\n#+begin_src bash\ncurl -XPOST http://host:port/clojure/nrepl-start\n#+end_src\n\n*** Stop it\n#+begin_src bash\ncurl -XPOST http://host:port/clojure/nrepl-stop\n#+end_src\n\n* License\n\nCopyright © 2020-22 - Ravindra R. Jaju\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\n[[http://www.eclipse.org/legal/epl-2.0][http://www.eclipse.org/legal/epl-2.0]].\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat [[https://www.gnu.org/software/classpath/license.html][https://www.gnu.org/software/classpath/license.html]].\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaju%2Fspring-boost","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaju%2Fspring-boost","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaju%2Fspring-boost/lists"}