Leiningen nREPL connect to remote repl with drawbridge - clojure

I'm trying to connect to a running clojure app package as a uberjar. I added [com.cemerick/drawbridge "0.0.7"] to my project.clj. But when I trying to connect with lein repl :connect http://ip:port/repl it is like it is not even connecting.
I get a stacktrace:
java.io.FileNotFoundException: Could not locate cemerick/drawbridge/client__init.class or cemerick/drawbridge/client.clj on classpath.
at clojure.lang.RT.load (RT.java:456)
clojure.lang.RT.load (RT.java:419)
clojure.core$load$fn__5677.invoke (core.clj:5893)
clojure.core$load.invokeStatic (core.clj:5892)
clojure.core$load.doInvoke (core.clj:5876)
....
clojure.lang.AFn.applyToHelper (AFn.java:171)
clojure.lang.Var.applyTo (Var.java:700)
clojure.main.main (main.java:37)
But when I run lein classpath I can find drawbridge there /root/.m2/repository/com/cemerick/drawbridge/0.0.7/drawbridge-0.0.7.jar
jar tf /root/.m2/repository/com/cemerick/drawbridge/0.0.7/drawbridge-0.0.7.jar
META-INF/MANIFEST.MF
META-INF/maven/com.cemerick/drawbridge/pom.xml
...
cemerick/drawbridge/client.clj
Any clues?

This looks like a plain old regression in Leiningen. I have submitted this as https://github.com/technomancy/leiningen/issues/2370.

Tested the same command on a older lein (clojure:lein-2.7.1) and it looks better. Something is maybe wrong on the server side but it connect at least.

Leiningen does not include Drawbridge anymore and you need to add it explicitly to plugins:
(defproject whatever "0.1.0-SNAPSHOT"
:plugins [[nrepl/drawbridge "0.2.1"]]))
See nREPL over HTTP(s) with Drawbridge in 2020

Related

Clojure / Leiningen - package jar resource into clojars

I have a question similar to Deploy 3rd-party jar to clojars?
I've pushed a small project into clojars using lein deploy. That project relies on a jar dependency that I've simply put in a folder on the local drive and imported in my :resource-paths as per below:
(defproject cljblpapiwrapper "0.1.0-SNAPSHOT"
:description ""
:url ""
:license {:name "" :url ""}
:dependencies [[org.clojure/clojure "1.9.0"]]
:resource-paths ["resources/blpapi-3.8.8-2.jar"]
:repl-options {:init-ns cljblpapiwrapper.core})
Now upon importing my deployed clojars repo in another project, it fails to find classes within the jar repo. I'm getting this trace:
#error {
:cause com.bloomberglp.blpapi.CorrelationID
:via
[{:type clojure.lang.Compiler$CompilerException
:message java.lang.ClassNotFoundException: com.bloomberglp.blpapi.CorrelationID, compiling:(cljblpapiwrapper/core.clj:6:1)
:at [clojure.lang.Compiler load Compiler.java 7526]}
{:type java.lang.ClassNotFoundException
:message com.bloomberglp.blpapi.CorrelationID
:at [java.net.URLClassLoader findClass URLClassLoader.java 382]}]
:trace
[[java.net.URLClassLoader findClass URLClassLoader.java 382]
[clojure.lang.DynamicClassLoader findClass DynamicClassLoader.java 69]
[java.lang.ClassLoader loadClass ClassLoader.java 424]
[clojure.lang.DynamicClassLoader loadClass DynamicClassLoader.java 77]
[java.lang.ClassLoader loadClass ClassLoader.java 357]
...
Looks to me like the jar didn't make it to clojars - how can I package it within my repo? Alternatively, how can I push it separately to clojars?
thanks,
Did you try to download your lib from clojars? Use the jar command to unpack the *.jar file and see if the lib is there.
Look at this repo: https://github.com/cloojure/tupelo-datomic
In the ./resources dir there is a jar file: datomic-free-0.9.5661-everything.jar
You may need to play around with the syntax in project.clj to make the uberjar on clojars form correctly. You may need to publish the dependency JAR file on a separate maven-compatible repo. Options include:
Deps.co - Created by the host of The REPL podcast
AWS S3 - there is a lein plugin to help with this
I think you need to bind the jar as dependency in your project.clj, resource path tells uber jar just include the file.

How to configure Jetty settings in project.clj and use Lein Ring in Clojure?

I would like to add some configuration to Jetty Adapter and run it with the lein-ring plugin, but i could not find any information.
I can run this configured from the main function by using lein run.
(jet/run-jetty main-handler {:port 8080 :join? false})
But I want to set those configurations in the project.clj so I can use "lein ring server".
The lein-ring documentation suggests you can put a map of options for your ring adapter in the project.clj file, like this:
:ring {:handler hello-world.core/handler
:adapter {:join? false
:port 8080}}
Though you probably do not want to use :join? false I'd think.

slf4j File Not Found error when building uberwar

I would like to understand why my Ring application is attempting to open the log file at compile time.
I have a webservice in Compojure and Ring. The application works without issue but whenever I compile the application to an uberwar or run lein ring server I get the below error from slf4j.
I don't understand what is causing the Clojure compiler to attempt to access this log file during compilation. The only clue which I have is that it only started happening when I included the Korma library.
If I create the directory I can get rid of the error, however, I want to understand why the application is attempting to open the log file at compile time.
log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: /var/log/ege/myservice/myservice.log (No such file or directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:133)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
at org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:207)
at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:307)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:172)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:104)
at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:809)
at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:735)
at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:615)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:502)
log4j configuration is a runtime configuration of your app. Korma uses log4j configuration for its usage in runtime. So, it's not surprising that when running lein ring server, korma uses log4j configuration for its logging and the log4j logging throws error cause it can not find the log directory.
As for the error thrown during lein check or lein ring war. Maybe you have some forms which attempts to connect to database or even do some query to your database in top-level of some of your namespaces.
maybe you have something like this:
(ns my-app.db
(:use korma.db)
(:use korma.core))
(def db (create-db (mysql {:db "my_db"
:user "root"
:password ""})))
;; this form below attempts to get a db connection
(def conn (get-connection db))
(defentity users)
;; this form below attempts to query the database
(select users)
when clojure compiles, it executes every form, thus, clojure connects to db or query the db. In other words, clojure runs a part of your app during compilation.
unrelated note
Everything above aside, you should separate the log4j configuration or any other runtime-configs for development environment and production environment.
I usually separate development environment and production environment configuration using :profiles in project.clj.
:profiles
{:production
{:ring
{:open-browser? false, :stacktraces? false, :auto-reload? false}
:source-paths ["prod-config"]}
:dev
{:dependencies [[ring-mock "0.1.5"] [ring/ring-devel "1.3.1"]]
:source-paths ["dev-config"]}}
I put my development's log4j.properties in dev-config dir and production's log4j.properties in prod-config dir.

Issue with lein ring uberjar and profiles

I am having troubles to make lein ring uberjar work with multiple profiles.
The following works:
lein new luminus profile-issue
cd profile-issue
lein ring uberjar
java -jar target\profile-issue-0.1.0-SNAPSHOT-standalone.jar
Now, when working with multiple profiles the following change to project.clj is important.
;add key to project.clj
:target-path "target/%s/"
Next attempt
lein clean
lein ring uberjar
java -jar target\profile-issue-0.1.0-SNAPSHOT-standalone.jar
Error: Could not find or load main class profile_issue.handler.main
The reason why it's important to split the target path into subdirectories when working with multiple profiles is explained here, around line 250. In a nutshell, when using :target-path "target/ you'll end up in troubles because different profiles compile into the same directory and when you start the REPL without a lein clean, you don't really know what you get.
And btw, when using :target-path "target/%s/" the jar and uberjar don't end up in the same directory which is weird.
Any idea?

How can I install Leiningen packages behind a firewall?

I use a local library to do some development, but the firewall prevents alot of internet sites. Is there a way to download artifacts manually?
My project.clj is:
https://github.com/zubairq/coils/blob/master/project.clj?
Update
From the comments given I am understanding that the steps to take are:
1) Install Maven
2) Find out which jars are in my project (How can I do this based on my project.clj?)
Dependency Tree
In order to figure out which jars your project needs you can do:
$ lein deps :tree
Which will show you something that is called a "dependency tree". It will look similar to:
[clj-time "0.5.0"]
[joda-time "2.2"]
[clojure-complete "0.2.3"]
[org.myproject/some-proto "0.0.1-20130523.145830-9"]
[org.flatland/protobuf "0.7.2"]
[ordered-collections "0.4.0"]
[org.flatland/schematic "0.1.0"]
[org.flatland/useful "0.9.0"]
[com.datomic/datomic-free "0.8.3862"]
...
Installing Jars with Lein
One simple way to install manually downloaded jars would be to use "lein-localrepo":
$ lein localrepo install [-r repo-path]
[-p pom-file]
<filename>
<[groupId/]artifactId>
<version>
Here are a couple of examples (given that you have downloaded the jars):
$ lein localrepo install foo-1.0.6.jar com.example/foo 1.0.6
$ lein localrepo install foomatic-1.3.9.jar foomatic 1.3.9
Take a look at the documentation for more features and examples.
Installing lein-localrepo
You can install lein-localrepo as a plugin by adding the following to your ~/.lein/profiles.clj:
{:user {:plugins [[lein-localrepo "0.5.2"]]}}
Lein Behind a Proxy Server
In case it is "ok" to use a proxy server, you can add it to ~/.lein/profiles.clj under jvm-opts
{:user {:jvm-opts ["-Dhttp.proxyHost=168.1.1.104" "-Dhttp.proxyPort=8080"]}}
where user is a profile name to use.
Or you can export http_proxy environment variable before launching lein.