Fork me on GitHub

I tried to follow the instruction from (I modified cd edge/tutorial.vent to cd edge/examples/tutorial.vent because the path in the doc is wrong) When I run $ ../bin/rebel --cljs -A:dev:build:dev/build , everything is fine and it showed a REPL. But when I enter (go) in the REPL, I got this error. How could I fix this.


Did you load the file up into the REPL?


@ no. First, I switch to the path edge/examples/tutorial.vent in terminal. And execute ../bin/rebel --cljs -A:dev:build:dev/build , which will bring up a REPL, then I enter (go)


and error showed up after (go)


I'm not familiar with Edge and this particular tutorial you're following. However, for the REPL to do anything useful like starting a project, you need to evaluate some code inside of it. Are you connected to the REPL through your code editor? If so, navigate to the file where the go function is defined and evaluate that file. Then the go function will be accessible inside your REPL.


I read some about Edge, have you seen this particular section in the docs?


@U07SWUQTH yeah.I tried terminal repl and emacs cider. Both have the same error. Below is the error with using cider. It looks like the figweel things have some problems.


Hi team, how can I create Java local date time in clojure for the given time? #object[java.time.LocalDateTime 0x7af2002a "2021-07-05T15:49:30.051"]


@vnazaryan OK you want to produce a LocalDateTime - what is the input you are getting to produce it from?



user=> (java.time.LocalDateTime/of 2020 7 5 9 1)
#object[java.time.LocalDateTime 0x737edcfa "2020-07-05T09:01"]


if you have all the individual values as numbers


anyway, your solution probably exists somewhere in the javadoc for LocalDateTime, it took me a minute and a half to figure that out from the page

Pavel Klavรญk16:07:37

@vnazaryan if you are unfamiliar with Java interop, I recommend checking this guide:


@noisesmith @pavel.klavik thanks a lot

๐Ÿป 5

I have deps.edn with :paths ["src" "resources" "../reportgenerator/build/web/WEB-INF/classes"] . In the classes folder I have itils folder and in it I have several classes that I want to import into clojure project. I import it like this (:import (utils Result SalXmlDocument Sample)) , but that gives me errors :clojure.error/class java.lang.ClassNotFoundException, :clojure.error/cause "java.lang.SalXmlDocument"},


@ruby.object Having :paths outside your project like that is deprecated (and will be disallowed), so that is not a solution.


Any reason why the change? We also often have mixed Clojure/Java projects where some Java code-gen runs as part of the Java build and puts generated classes in some folder that are needed for the REPL.


I'll defer to @U064X3EF3 to explain with :paths outside a project was deprecated.

Alex Miller (Clojure team)18:07:41

Having generated classes in a folder is fine, it should just be a folder inside the project

Alex Miller (Clojure team)18:07:45

Accessing arbitrary paths outside the project root is a potential security issue and the Clojure CLI will currently print a warning if you do this (and eventually we plan to error in this case)


What's the security issue? If someone can modify my deps.edn, they can as easily just put a class inside the same folder.


In my case, the classes are generated outside the project folder. Because they're actually part of a dependency. The Java build is setup to generate classes, and build multiple projects and dependencies, and then it grabs the union of it all, and puts it in the workspace folder, inside the workspace folder are multiple projects. So now inside one of those projects I want to start a REPL, and so I need to point it to the classes folder of the workspace.

Alex Miller (Clojure team)17:07:35

if they're a dependency, then use a :local/root dep

Alex Miller (Clojure team)17:07:15

we are definitionally saying that a project's paths are descendants of the project root only

Alex Miller (Clojure team)17:07:29

if you pick up a lib with external :paths as a git dep, this will point to some random point on the dependee's drive - this is not meaningful across users


Will local/root work for a folder of .class files?

Alex Miller (Clojure team)17:07:23

if you create a deps.edn pointing to that dir in :paths, yes


That's the problem, I need it to play along with the Java build system

Alex Miller (Clojure team)17:07:02

how is that at odds with a Java build system?


So those Java dependencies will not have deps.edn of their own


And some of them are code-gen packages, they don't even have Java source, but XML that generates Java client code

Alex Miller (Clojure team)17:07:59

are these Java deps you control? if so, you can add a deps.edn


I do not, big company, lots of teams, those are other teams packages

Alex Miller (Clojure team)17:07:33

and you just get folders of classes? not jars?

Alex Miller (Clojure team)17:07:50

:local/root can point to a .jar file


Yes, though there might be a corresponding Jar as well. I would need to verify. The code-gen package is the one I'm not sure if it would.


Currently I use lein and a plugin that lets me add my own paths to the lein classpath. I was hoping to move to deps.edn at some point. That's why I ask

Alex Miller (Clojure team)17:07:56

I imagine there are potentially many ways to accomplish a workaround, but you're out of normal scope for a deps project


So the envisioned development flow if say you work on a Java package and a Clojure package where the Clojure package depends on the Java one is that you'd build the Java one locally to a Jar and use local/root in the Clojure one?


I would probably colocate them so I could work on the Java and Clojure together, which solves a lot of these problems, but then I'm a fan of monorepos anyway, even multi-lingual ones.


Then you can have the classes folder that the Java builds into be a :paths entry within the (Clojure) projects, since they are both in the same tree.


What if :paths didn't allow paths outside the folder, but it was allowed for :extra-paths? I understand as the main :pathsits weird that a project could depend on things that are environment dependent. But extra-paths will always be used in an alias or other "profile" like things, used for development.


:extra-paths is just added to :paths so I think the same rules should apply. If something is external to your project, it's a dependency not a path.


In my case, I have to work with what we have and it's setup to not be a monorepo. So each package is its own repo. In the past I used symlinks, but those require a lot of manual labor to maintain. And every new hire that joined the team you'd have to set it up for them as well. With relative paths, a simple convention works, you just say clone all your repos in the same folder, and it'll all just work with relative paths


As a dependency it works too, but local/root only supports Jar dependencies for Java. So maybe it could also support Java class folders?


Though I can also see an issue with resource folders if treated purely as a dependency.


If each project is separate, each project should produce a reusable artifact. A directory full of .class files is not an "artifact".


That's a matter of perspective ๐Ÿ˜‚. The build system is quite sophisticated. So actually when it pull down dependencies it doesn't pull down Jars, but .class files into a global local folder under versioned paths. If you have many packages that all depends on the same version of the class it'll all symlink things so the dependency closure of each package is pointing to the correct place. And it does the closure at a workspace level based on the "main" package as the start entry.


I might experiment with seeing if I can set things up with deps.edn without using :paths and I'll report back. Maybe local/root with Jars can work


That's a very strange definition of "sophisticated" in my view... ๐Ÿ™‚


I don't know, how deps is encouraging git deps, you could argue in Java Jars are complicated and a build folder of classes with a launch script in it would have been simpler


I think the reason it does that is because it supports more than just Java. The artifact repository has artifacts for all programming languages


So for example I could take a dependency on a package that has an executable script, and it would pull it down as well

Alex Miller (Clojure team)18:07:59

tools.deps as a library is extensible to whatever custom "dep" type you'd like to plugin via the extension points (but you're at that point outside what the Clojure CLI currently supports)


Hum, I just remembered that with lein I even need to custom generate some paths each time it runs dynamically.


If I extend a customer dep type, can I plug my extension into deps.edn in a way that tools will transparently work with it?


Like say I need a custom deps type, and I define things with it in my deps.edn. And now I want Cursive to start a repl with deps.edn but for it to work with my custom deps type?


Like lein has :plugins for that

Alex Miller (Clojure team)18:07:45

the Clojure CLI does not yet have a way to define and load custom extensions

Alex Miller (Clojure team)18:07:25

Cursive can use tools.deps directly but also does not have any place to do that afaik

Alex Miller (Clojure team)18:07:45

but if you use tools.deps as a library, it's just a matter of loading a namespace that extends the multimethods

Alex Miller (Clojure team)18:07:19

I've been delaying doing anything with the CLI until someone actually cared :)


Fair fair. For now I'm happy with lein, the point is mostly to get tools to play nice with our internal package manager. And Lein with some plugins did the trick. Once I experiment with trying to switch to tools.deps instead I'll report my blockers if any.


(and we can follow-up in #tools-deps)

๐Ÿ‘ 2

what can i do to accecc the tree of java classes?

Drew Verlee16:07:25

i'm not sure myself, does the :local path key support that?


is symbolic link good enough?


what are the options? how can I do a non trivial java interop?

Drew Verlee16:07:46

there might be a very good reason, i just haven't run into it or i'm confused, why are your class files not in a jar?


I have a legacy netbeans app and I was thinking about using it's classes to import to clojure and create a jar file from clojure code to be used by the netbeans app


is it overly too convluted?


is it possible to gradually refactor the old app into clojure? or should I quit the job?

Drew Verlee17:07:45

if you can produce a jar from the netbeans app, then i believe deps should be able to pick it up and use the code. Then you can recompile. But I would wait tell someone with more experience doing this answers. Your question was interesting because i hadn't ever considered the situation.


this trivial example works


problems start with real life app


It sounds like you are really more interested in calling into Clojure from the legacy NetBeans app?


(and ultimately replacing the Java code with Clojure, working from the ground up)


There are two or three possible approaches but the one I prefer -- because it's how we refactored our legacy app to use Clojure (and then, ultimately, replaced the legacy app completely with Clojure) is to leverage Clojure's Java API


You can start by adding Clojure as a regular dependency on your legacy app -- Clojure is "just" a library, like anything else you're already using in the legacy code. And gradually, as you write more Clojure to replace the Java code, start adding more Clojure libraries as dependencies.


You would also need your Clojure project's src folder added to the classpath of your legacy app (so the legacy project could "see" your Clojure code when it is referenced via the Java API).


that is what I had in mind. to some extent you confirm my idea. But I am stuck at the clojure being a library of my legacy app. For some hope of success that clojure library has to work and finding the examples is not easy. to have a woking library for the legacy app I need to be able to import some classes.


I had success with trivial app also at some point I was able to import legacy java classes to my clojure app, but for some reason it stopped working.


I know nothing about NetBeans, but the first step will be to add org.clojure/clojure as a dependency to your Java project (with version "1.10.3") and in your existing Java code, try out what I linked to above: referencing some clojure.core functions.


The problem is calling clojure from java side


public static String passTheData(SalXmlDocument info) { // use the new class for more talking to clojure"hello");;


hello did work


but how do i pass to clojure an instance of a class?


is my strategy correct?


Did you read the page I linked, explaining Clojure's Java API?


You can avoid all the gen-class pain.


not yet, i will now


that page does not say what should be the corresponding code on clojure side

bigos17:07:23 mentions only Objects, how do I pass a hash, or instance of an object


Everything in Java is an Object. You can pass in anything.


And the Clojure code is just regular Clojure code.


so why does medthod give me errors


:methods [#^{:static true} [foo [String] void] #^{:static true} [ldata [SalXmlDocument] void] #^{:static true} [tryme [Object] void]]


do i even need to declare the types of arguments


You don't need any of that if you call into Clojure from Java via Clojure's Java API that I linked to.


i'll give it a try


found good example


question how to do it with deps edn


No, you don't want deps.edn for this: just add Clojure to your existing Java project. You'll use whatever tool your Java project uses to build the Java code already.


You know how to build the existing NetBeans Java project, yes @ruby.object?


And you have a list of its current dependencies in some NetBeans config?


i can find it


i have a project.xml file with jar dependencies


Excellent! So you can add Clojure to that.


how do i do it?


because at the moent i was using clojurte to create jar file


Your project.xml has sections like this?



Clojure is "just" a dependency like:



And you should be able to rebuild your Java project and it will add Clojure to it.


<library dirs="200"> <file>${file.reference.mockito-all-1.10.16.jar}</file> <path-in-war>WEB-INF/lib</path-in-war> </library>


i was looking in the wrong place, one moment please


mind you it's netbeans 8 ๐Ÿ˜ž


The NetBeans UI probably has an option somewhere to "add dependency" if you're used to doing it that way...


(like I say, I have never used NetBeans...)


well i use ant


it is so old


Well, something somewhere in the project has to have the list of dependencies. When you find that, you can add Clojure to it.


i foud a dialog for it


and it leads to the jar dialog


has the option to download the jar file, I'm back on track


That will not work. You need to specify Clojure as a dependency not a downloaded library.


Clojure itself depends on two other libraries. Downloading the JAR will not give you those libraries so your code will fail (in ways you will find hard to debug).


Please figure out how to add dependencies to your Java project and add Clojure that way.


so does that mean that i need to find ways to convert the project to maven first?


As I keep saying, I know nothing about NetBeans. Somehow, somewhere, your existing Java project must have a way of declaring/specifying its existing dependencies. Those are being fetched from Maven. Clojure is on Maven. So you can add Clojure as a dependency to the existing Java project somehow and that's all you need.


NetBeans itself definitely lets you add new dependencies to a project (not JAR files, not class libraries, actual dependencies). You need something that understands Maven-style dependencies to fetch Clojure for you, so that transitive dependencies are also fetched.


Who built this project in the first place? Can you ask them about adding a dependency?


(since you said "or should I quit the job?" I assume you have colleagues you can ask about this project)


they no longer work here


the company is interviewing a java programmer this week I am not a java programmer


Well, then you're probably not going to be able to mix Clojure and Java if you can't find out or figure out how to add Maven-style dependencies to that existing project, sorry.


Once they hire a Java programmer, there will be someone who can set that up for you.


I'm sure there are a lot of legacy projects that would benefit from clojure, but why is is so hard, are people so fed up with the old projects so that they rewrite them from scratch?


It isn't hard. It just assumes some knowledge about the Java ecosystem which you don't have, unfortunately.


thank you very much for your help, especially for your deps.edn that I regularly copy


have a good night


Sorry I can't really help you with this ๐Ÿ˜ž


you are not the first one


usually people give up much sooner


Haha... OK, fair enough.


I have emailed my boss saying i am making progress. i will have some explaining tomorrow


If it was publicly accessible, I could probably dig into it some more, but right now I don't even know what to suggest you look for in the project (since I gather it doesn't have pom.xml which would be the telltale sign of Maven?).


Is the build.xml file just running javac with no dependency management stuff in place at all?


(I can't imagine the code uses no external libraries at all but I suppose that is technically possible)


$ tree ./nbproject/ ./nbproject/ โ”œโ”€โ”€ ant-deploy.xml โ”œโ”€โ”€ build-impl.xml โ”œโ”€โ”€ build-impl.xml~ โ”œโ”€โ”€ โ”œโ”€โ”€ private โ”‚ย ย  โ”œโ”€โ”€ โ”‚ย ย  โ””โ”€โ”€ private.xml โ”œโ”€โ”€ โ”œโ”€โ”€ project.xml โ””โ”€โ”€ rest-build.xml


$ ls ./*.xml ./build.xml


jacekp@EID6043:~/code/AAA-java/reportgenerator$ tree ./lib/ ./lib/ โ”œโ”€โ”€ bcmail-jdk15on-1.67.jar โ”œโ”€โ”€ bcpg-jdk15on-1.67.jar โ”œโ”€โ”€ bcpkix-jdk15on-1.67.jar โ”œโ”€โ”€ bcprov-jdk15on-1.67.jar โ”œโ”€โ”€ cds.astro.jar โ”œโ”€โ”€ clojure-1.10.2.jar โ”œโ”€โ”€ commons-lang-2.6.jar โ”œโ”€โ”€ core-renderer-R8.jar โ”œโ”€โ”€ javacsv.jar โ”œโ”€โ”€ javax.mail-1.6.2.jar โ”œโ”€โ”€ lidlcsvreport.jar โ”œโ”€โ”€ mockito-all-1.10.16.jar โ”œโ”€โ”€ multipart.jar โ”œโ”€โ”€ opencsv-5.1.jar โ”œโ”€โ”€ openpdf-1.3.23.jar โ””โ”€โ”€ unbescape-1.1.6-SNAPSHOT.jar


the code is 10-15 years old


Out of curiosity, what version of Java is it running with?


$ tree -d ./src/ ./src/ โ”œโ”€โ”€ conf โ””โ”€โ”€ java โ”œโ”€โ”€ emailing โ”œโ”€โ”€ exceptions โ”œโ”€โ”€ sal โ”‚ย ย  โ”œโ”€โ”€ calculations โ”‚ย ย  โ”œโ”€โ”€ reports โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ animal_feed โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ content_producers โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ micro โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ tools โ”‚ย ย  โ”œโ”€โ”€ stamps โ”‚ย ย  โ””โ”€โ”€ user_options โ”œโ”€โ”€ servlets โ”œโ”€โ”€ utils โ””โ”€โ”€ xml โ””โ”€โ”€ regulatory_methods


$ java -version java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12)


src folder has dozens of classes in the src folder


At least you're on Java 8 ๐Ÿ™‚


OK, so since you've gotten as far as manually downloading Clojure 1.10.2, here are the other libs you'll need to download to at least move forward:

org.clojure/clojure 1.10.2
  . org.clojure/spec.alpha 0.2.194
  . org.clojure/core.specs.alpha 0.2.56


If you download those manually from Maven, like you did for Clojure, and put them in lib, you should at least be able to try the Java -> Clojure calls into clojure.core per the example linked somewhere above.


It'll be painful to add any new Clojure libraries or update Clojure etc but it should at least get you to a working state for something basic.


Then, in some Java code in the project, you should be able to import; and import clojure.lang.IFn; and then do this:

IFn plus = Clojure.var("clojure.core", "+");
plus.invoke(1, 2);


As for writing your own Clojure code and being able to require and invoke that, you'll need your (Clojure) src folder to be on the project's classpath but I'm sure where to suggest putting that or how to configure the app to add it...


In the Java code you could call System.getProperty( "java.class.path" ); to see what is on the current classpath and maybe there's an "obvious" safe place to put your src folder in some directory on that classpath...?


no error bu bnothing is printed


i guess i can try to figure it out later


you think about the question i was asking myself about the src for clojure


I expect you'd have to log the result or print it -- however the current project writes stuff to a console log...


sadly i do not know where to star and I need to call it a day


That getProperty() call is just going to return a string.


OK, well, good luck tomorrow. We'll be here ๐Ÿ™‚


ant -f /home/jacekp/code/AAA-java/reportgenerator -Djavac.includes=servlets/ -Ddirectory.deployment.supported=false -DforceRedeploy=false -Dbrowser.context=/home/jacekp/code/AAA-java/reportgenerator/src/java/servlets/ -Ddebug.class=servlets.GeneratorServlet debug-single-main init: deps-module-jar: deps-ear-jar: deps-jar: compile-single: Generating Report - ReportID : 1388907 - Report Type : +44 - UserName : jacekp - Location : Concept Loading KeyStore File URL: http://localhost:10000/xml/report/generate/1388907Converting stream to string Starting loading groups from XML group = Pesticide Screen (GC CSOPP611 & LC CSOPP603 Reg) group = Fosetyl-Al (sum fosetyl + phosphorous acid and their salts, express as fosetyl) group = Miscellaneous group = Miscellaneous group = Pesticide Screen (GC CSOPP611 & LC CSOPP603 Reg) Finished Loading Groups from XML Report Unit : 1' : kg Report Unit : 3' : mg for 5 : null Parsing new report : before trying clojure after trying clojur


public static String passTheHash(SalXmlDocument info) { System.out.println("before trying clojure"); IFn plus = Clojure.var("clojure.core", "+"); plus.invoke(1, 2); System.out.println("after trying clojure");


System.out.println( plus.invoke(1, 2) );


Then at least you should see the result printed ๐Ÿ™‚


before trying clojure 3 after trying clo




now how do i invoke real clojure code?


Well, you have to figure out how to add a src folder to the app's classpath somehow.


Then you just write your Clojure code in that folder, and use var/`require` to make it accessible to Java.


i just had idea


i will just commit what i have so far


i do not want to lose your precious code


IFn require = Clojure.var("clojure.core", "require");
IFn yourFunc = Clojure.var("your.namespace","your-func");


do i put the hole project?


lidlcsvreport$ tree . โ”œโ”€โ”€ โ”œโ”€โ”€ classes โ”‚ย ย  โ””โ”€โ”€ sal โ”‚ย ย  โ””โ”€โ”€ reports โ”‚ย ย  โ””โ”€โ”€ LIDL_Pesticide_Report.class โ”œโ”€โ”€ copy-java-classes โ”œโ”€โ”€ deps.edn โ”œโ”€โ”€ doc โ”‚ย ย  โ””โ”€โ”€ โ”œโ”€โ”€ LICENSE โ”œโ”€โ”€ lidlcsvreport.jar โ”œโ”€โ”€ pom.xml โ”œโ”€โ”€ โ”œโ”€โ”€ โ”œโ”€โ”€ resources โ”œโ”€โ”€ src โ”‚ย ย  โ””โ”€โ”€ sgs โ”‚ย ย  โ””โ”€โ”€ lidlcsvreport.clj โ””โ”€โ”€ test โ””โ”€โ”€ sgs โ””โ”€โ”€ lidlcsvreport_test.clj


or just src of the clojure project?


Start small. Start by just adding a src folder and some simple code and make sure you can call it.


Remember that this is a Java project: the deps.edn etc is irrelevant.


i did not know that


You're not building Clojure to a JAR or compiling it to classes.


perhaps i shold remove the jar cleated by deps.edn


You're using Clojure source code inside the Java project, and relying on the require invocation to load and compile it.


in netbeans i hace sources dialog with src and test declared


maybe this is the way out


I don't think so. For a Java project, that's just where to find the Java source code -- it's not about the classpath.


System.out.println( System.getProperty( "java.class.path" ) );
^ that in your Java code will print out what the class path is when the Java code runs.


i have created clojure-src folder at the root of java project and uses the properties/sources dialog to add it to the project


I don't think that will work because I don't think that will affect the classpath.


claspath is void


do i need to import systemk?


What does System.out.println( System.getProperty( "java.class.path" ) ); print?


before classpath /home/jacekp/code/AAA-java/reportgenerator/build/web/WEB-INF/classes:/home/jacekp/code/AAA-java/reportgenerator/lib/bcmail-jdk15on-1.67.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/bcpg-jdk15on-1.67.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/bcpkix-jdk15on-1.67.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/bcprov-jdk15on-1.67.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/cds.astro.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/commons-lang-2.6.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/core-renderer-R8.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/javacsv.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/javax.mail-1.6.2.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/mockito-all-1.10.16.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/multipart.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/opencsv-5.1.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/openpdf-1.3.23.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/unbescape-1.1.6-SNAPSHOT.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/clojure-1.10.2.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/core.specs.alpha-0.2.56.jar:/home/jacekp/code/AAA-java/reportgenerator/lib/spec.alpha-0.2.194.jar:/home/jacekp/netbeans-8.2rc/enterprise/modules/ext/jaxrs-2.0/ after classpat


Thanks. Just a sec...


lots of jboss


Hmm, so /home/jacekp/code/AAA-java/reportgenerator/build/web/WEB-INF/classes is the only actual folder on the classpath...


that is where the classes appear when I press compile button


Yeah, expected. I was hoping for some other folder where you could safely put Clojure source code ๐Ÿ™‚


When we were adding Clojure to our legacy app, we edited the app's config to add an additional folder to the classpath at startup (our Clojure src folder).


Do you always run the project via ant like that? Or does it normally run as a web app?


its a web app when it's deployed


OK, so ant is just for testing it?


but i use mockito to cheat around that


mockito is for testing


ant is for buildung war file that is rsynced to the server


It looked like you were using ant to actually run the code for testing that the Clojure invocation worked.


public static void main(String[] args) throws ServletException, FileNotFoundException, IOException, MissingValuesException, NoSuchAlgorithmException, CertificateException, KeyStoreException { HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse response = mock(HttpServletResponse.class); // insert parameters here // when(request.getParameter("reportid")).thenReturn("1366796"); when(request.getParameter("reportid")).thenReturn("1388907")


Right, and that's the "single-debug-main"?


yes, almost some classes have their debug mains


could that be a clue?


I wouldn't bother trying to follow something so old.


If you have a small, simple Clojure project, you can ask Clojure to compile a namespace to .class files in a specific target directory from the REPL:

user=> (binding [*compile-path* "/home/jacekp/code/AAA-java/reportgenerator/build/web/WEB-INF/classes"]
          (compile "your.namespace"))
That would let you write Clojure in a separate folder, and compile it into that classes folder so it would be accessible to the Java code (via the var/`invoke` calls).


What I'm trying to help you avoid is having to write all the gen-class stuff since that's so painful and also it requires the compiled Java classes to be on your Clojure classpath -- which would mean your Clojure project would have to live in that same tree so it could be on your :paths. Code compiled per above, into the WEB-INF/classes folder, would then be on the classpath when the Java code runs so that your Java code could require it -- but I worry that classes folder gets cleaned out each time to build the Java code (which would erase your Clojure code).


You could also build an uberjar of your Clojure project -- without AOT -- and put that in lib (you wouldn't need the Clojure JARs in lib then because Clojure would be in your uberjar) and, again, access the Clojure code via require as above.




i have :/home/jacekp/code/AAA-java/reportgenerator/src/clojure: in the classpath


the dialog for adding jars is confusing


it allows aslo to add folders


Yay! :thumbsup::skin-tone-2:


So now you can put example.clj unto that src/clojure folder with (ns example) and a function in it, and try requiring/invoking it from the Java code.


(baby steps, to verify each new piece works!)


i tried somethis else and now i will be wiser and will follow the baby steps


Exception in thread "main" java.lang.IllegalStateException: Attempting to call unbound fn: #'example/requi


// any other namespace than clojure.core needs to be "required" IFn require = Clojure.var("example", "require"); require.invoke("example")); IFn foo = Clojure.var("", "foo"); System.out.println(foo.invoke());


after classpath we have another failure add: null


(ns example) (defn foo [] (println "we have another failure"))




we never agreed on paying you evening rate so I am not expecting to give you lots of money


but your effort needs some reward


IFn require = Clojure.var("clojure.core", "require"); // this is a core function



IFn foo = Clojure.var("example", "foo"); // needs the ns for example/foo


I got it working ๐Ÿ™‚ thank you. I am sure I will ask more questions on slack, but I will always remain grateful for your help.


Hey team, I am playing with the slack api. To use their thing, I need to reify the To do that, I wrote this:

(let [config ;;
        app (App. config)
        server  (SlackAppServer. app)]
    (.command app "/hello"
              (reify SlashCommandHandler
                (apply [this req ctx]
                  (.ack ctx ":wave Hello!"))))
    (.start server))
The error I get is:
[qtp740546585-42] ERROR com.slack.api.bolt.servlet.SlackAppServlet - Failed to handle a request - class java.lang.String cannot be cast to class (java
.lang.String is in module java.base of loader 'bootstrap'; is in unnamed module of loader 'app')                          
java.lang.ClassCastException: class java.lang.String cannot be cast to class (java.lang.String is in module java.base of loader 'bootstrap'; com.googl
e.gson.JsonElement is in unnamed module of loader 'app')
        at consistent_slack.core$_main$reify__1646.apply(form-init998480002803844197.clj:15)
My understanding of reify, is a bit wonky. Any guidance on how I can think about what is happening here, much appreciated!


ack is here and expects JsonElement but you passed a String -- which is what the error says.

๐Ÿ‘ 4

Thanks for the resp Sean! Based on the SlashCommandHandler interface, I thought the context was this: which has a ack(String implementation. Am I misunderstanding how above is functioning?

Drew Verlee17:07:04

what the heck java

๐Ÿ˜• 4
Drew Verlee17:07:51

what does clash command response.builder do

Drew Verlee17:07:15

i mean , imagine it tries to build a json from a string


I think the issue here is that those types are available via generics to the Java compiler -- but generic types don't exist in compiled code -- they are erased -- so the information that Clojure has available only has the raw types.


(generics are compile-time polymorphism, effectively, but not actual dynamic polymorphism)


Most of slack's APIs are just http calls that receive and return json. I would probably ignore their Java library and just interface with their http API

โ˜๏ธ 6

Yes, that's how we interact with Slack from Clojure. Far easier than their ridiculously convoluted Java SDK.


The addition of generics was about when I quit Java. Having spent years on the C++ Standards Committee, working on the specification of templates, I didn't want to deal with a watered down version of that in Java!


Thanks team! > I think the issue here is that those types are available via generics to the Java compiler -- but generic types donโ€™t exist in compiled code -- they are erased -- so the information that Clojure has available only has the raw types. Appreciate the depth Sean. Would love to understand this more. Which type is being erased here? (i.e I am not sure what you mean by โ€œthis type is available via generics to the Java compilerโ€, but not to our compiled code via Clojure) (indeed http api may be best, but am trying to smack a few things together as demo, and ideally would like to get this guy to work. Though yeah โ€” oof โ€” very darn convoluted)

Drew Verlee17:07:48

I think of you pass a valid Json string I think it might work. I don't think :hello is valid


@stopachka Java generics only exist in the (Java) compiler. They don't exist at runtime -- they're not in the .class files -- which is what Clojure has to work with.


@U0DJ4T5U1 Iโ€™m not quite sure I understand:

(.command app "/hello"
          (reify SlashCommandHandler
            (apply [this req ctx]
              (.ack ctx ":wave Hello!"))))
Do you mean wrap ":wave Hello!" like this ? "\":wave Hello!\""


@seancorfield โ€” wanted to confirm โ€” in this context is the generic โ€œJsonElementโ€?


The <CTX extends Content> stuff is the generics.


Aha! I see


(wait, maybe not โ€” apologies for the noob questions โ€” looking now at where this is written)


I think I understand what you mean, but am not sure where this is happening. ^ this says CTX extends Context, but why is this a generic? (I thought this was inheritence)

Drew Verlee17:07:08

I was thinking "1", instead of ":hello..."


Generics are compile-time only for Java. They do not exist in the bytecode so no other languages see any of that generic stuff when compiling against Java .class files. I don't know how to say it any differently.


Thanks for bearing with me Sean. What I donโ€™t understand is the following: I donโ€™t see where a generic is written in the source code above.

The <CTX extends Content> stuff is the generics.
Where is this stuff?


Aah! Okay, this makes sense. Thank you!


So if I understand correctly: โ€ข The above interface is only understood by java, as it uses generics โ€ข From clojure side, it doesnโ€™t know the class of CTX when our SlashCommandHandler runs, and defaults to the base Context type



(.command app "/hello"
          (reify SlashCommandHandler
            (apply [this req ctx]
              (let [^SlashCommandContext x ctx]
                (.ack x "hello!")
The following makes it work! Thanks for bearing with me and for the time @seancorfield @U0DJ4T5U1


Woohoo! ๐Ÿ™‚

๐Ÿ”ฅ 2

Okay, one more esoteric java noob q:

import com.slack.api.model.event.ReactionAddedEvent;

app.event(ReactionAddedEvent.class, (payload, ctx) -> {
If I wanted to convert this to clojure, how would I convert passing in ReactionAddedEvent.class ? I am trying:
(.event app
        (class MessageEvent)
        (reify BoltEventHandler
          (apply [this evt ctx]
            (log/info "ctx")
            (log/info ctx))))
But am getting:
{:type java.lang.IllegalArgumentException                                              
   :message Unexpectedly failed to register the handler                                  
   :at [ event 564]}]     
Which makes me think I am not correctly converting MessageEvent.class


@stopachka (class MessageEvent) should be just returns Class , you actually want MessageEvent which is the clojure equivalent of java's MessageEvent.class



(ins)user=> (class Number)
(ins)user=> Number


it's a good example of boilerplate elimination I think, what would Number be other than the class Number?


I'm wondering now whether there's any value other than nil that returns something other than Class from (comp class class)


probably nothing


user=> (into #{} (map (comp class class))
              [nil 1 Number "" String Double/NaN 'foo])
#{nil java.lang.Class}


ah, makes a loot of sense! Thanks @noisesmith, and clojure ftw!!

Maxime D20:07:22

Hi everyone. Brand new to Clojure and can't stop reading for the last two weeks. Interested to start a SaaS (learning) project with Clojure and was wondering if it is considered OK to use Vue or React without going the SPA road. A bit like adding some React or Vue components only in the html templates (using Semler). I guess it is possible but would like to hear about your experiences.


I don't see a problem with that. I've also made something for pages that need a tiny bit of CLJS, for quickly setting up something, without going through the hoops of setting up a CLJS project first.

๐Ÿ‘ 2
๐Ÿ‘€ 2

๐Ÿ˜ฎ clojurescript in the <script> tag!

๐Ÿ‘€ 2
Maxime D02:07:05

Thanks. Not sure to see the plus side of using cljs here though. Will have to tinker a bit. Enough reading, coding time.


big thanks to @seancorfield for his help ๐Ÿ™‚

โค๏ธ 2