jacekschae / learn-reitit-course-files

🎦 Learn Reitit course files for building Cheffy REST API
https://www.learnreitit.com
37 stars 16 forks source link

11 - Integrant Reloaded: Thread.stop() deprecated & (halt) not working #1

Closed ancaemcken closed 3 years ago

ancaemcken commented 3 years ago

Hi Jacek,

Noob at Clojure and Java here! I don't know if these two are related, but here goes.

I'm getting the following error in the REPL when trying to eval (halt) from user.clj.

(halt)
Execution error (NullPointerException) at cheffy-api.server/eval3093$fn (server.clj:36).
Cannot invoke "Object.getClass()" because "target" is null

The IDE is also greying out and striking through the stop method with deprecation warnings: java.lang.Thread.stop is marked as deprecated and java.lang.ThreadGroup.stop is marked as deprecated

(defmethod ig/halt-key! :server/jetty
  [_ jetty]
  (.stop jetty))

My setup: Fedora 32 64-bit IDEA community (latest) with Cursive. Clojure 1.10.0 JDK adopt-openjdk-15.0.1

I tried googling the stuff and became none the wiser for it.

What am I missing? Any directions for a fix?

ancaemcken commented 3 years ago

I've figured it out.

I had a nasty extra space after .stop. And I had reversed the lines in the :server/jetty bit (println was the last).

Sorry for the noise :facepalm:

m1nhtu99-hoan9 commented 2 years ago

I encountered the same issue, but the root cause is different 😅

During debugging with user namespace already loaded to the REPL, evaluating state/system yielded:

{:cheffy/app #object[clojure.lang.AFunction$1 0x4d7be557 "clojure.lang.AFunction$1@4d7be557"], 
 :server/jetty nil}

The reason for :server/jetty being null is because my below ig/init-key implementation returns null instead of the jetty server:

(defmethod ig/init-key :server/jetty
  [_ {:keys [handler port]}]
  {:pre [(some? handler) (int? port)]}

  (run-jetty handler {:port port :join? false})
  (println (str "Ya know what? App running at port " port)))

The fix is simple:

(ns chaffy.server
  (:require [environ.core :refer [env]]
            [integrant.core :as ig]
            [reitit.ring :as ring]
            [ring.adapter.jetty :refer [run-jetty]])
  (:import (org.eclipse.jetty.server Server)))

(defmethod ig/init-key :server/jetty
  [_ {:keys [handler port]}]
  {:pre [(some? handler) (int? port)]}

  (let [^Server server (run-jetty handler {:port port :join? false})]
    (println (str "Ya know what? App running at port " port))
    server))

Or, just swapping the order of the two last expressions would do the work:

(defmethod ig/init-key :server/jetty
  [_ {:keys [handler port]}]
  {:pre [(some? handler) (int? port)]}

  (println (str "Ya know what? App running at port " port))
  (run-jetty handler {:port port, :join? false}))