I tried to follow the instruction from https://github.com/juxt/edge/tree/master/examples/tutorial.vent
(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.
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"]
Did you load the file up into the REPL?
@vnazaryan OK you want to produce a LocalDateTime - what is the input you are getting to produce it from?
eg.
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
@vnazaryan if you are unfamiliar with Java interop, I recommend checking this guide: https://clojure.org/reference/java_interop.
@https://app.slack.com/team/U07SWUQTH 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)
@noisesmith @pavel.klavik thanks a lot
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"},
why?
@ruby.object Having :paths
outside your project like that is deprecated (and will be disallowed), so that is not a solution.
what can i do to accecc the tree of java classes?
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?
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?
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 https://github.com/slackapi/java-slack-sdk/blob/ce13f06e99d3b2c9234d871bbb2ebeedb9fdf282/bolt/src/main/java/com/slack/api/bolt/handler/builtin/SlashCommandHandler.java#L9 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 com.google.gson.JsonElement (java
.lang.String is in module java.base of loader 'bootstrap'; com.google.gson.JsonElement is in unnamed module of loader 'app')
java.lang.ClassCastException: class java.lang.String cannot be cast to class com.google.gson.JsonElement (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!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.
https://github.com/bigos/JavaApplication3/blob/master/clojure/responder/src/jac/responder.clj
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)
ack
is here https://github.com/slackapi/java-slack-sdk/blob/master/bolt/src/main/java/com/slack/api/bolt/context/Context.java#L92 and expects JsonElement
but you passed a String
-- which is what the error says.
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 https://clojure.org/reference/java_interop#_calling_clojure_from_java
Thanks for the resp Sean! Based on the SlashCommandHandler
interface, I thought the context was this: https://github.com/slackapi/java-slack-sdk/blob/ce13f06e99d3b2c9234d871bbb2ebeedb9fdf282/bolt/src/main/java/com/slack/api/bolt/context/builtin/SlashCommandContext.java#L51-L53
which has a ack(String
implementation. Am I misunderstanding how above is functioning?
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.
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.
what the heck java
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).
@ruby.object How does that sound?
what does clash command response.builder do
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
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!
I'll defer to @alexmiller to explain with :paths
outside a project was deprecated.
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)
I think of you pass a valid Json string I think it might work. I don't think :hello is valid
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.
@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.
I had success with trivial app https://github.com/bigos/JavaApplication3 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 hmm.report.foo("hello"); hmm.report.passdata(info);
hello did work
but how do i pass to clojure an instance of a class?
is my strategy correct?
@drewverlee 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!\""
Did you read the page I linked, explaining Clojure's Java API?
You can avoid all the gen-class pain.
@seancorfield — wanted to confirm — in this context is the generic “JsonElement”?
No.
not yet, i will now
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)
that page does not say what should be the corresponding code on clojure side
I think I understand what you mean, but am not sure where this is happening. https://github.com/slackapi/java-slack-sdk/blob/ce13f06e99d3b2c9234d871bbb2ebeedb9fdf282/bolt/src/main/java/com/slack/api/bolt/context/builtin/SlashCommandContext.java#L24 ^ this says CTX extends Context, but why is this a generic? (I thought this was inheritence)
I was thinking "1", instead of ":hello..."
https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.html 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.
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?i'll give it a try
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
Okay,
(.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 @drewverleehttps://stackoverflow.com/questions/46436476/how-to-invoke-clojure-function-directly-from-java
found good example
Okay, one more esoteric java noob q:
import com.slack.api.methods.response.chat.ChatPostMessageResponse;
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 [<http://com.slack.api.bolt.App|com.slack.api.bolt.App> event App.java 564]}]
Which makes me think I am not correctly converting MessageEvent.class
https://github.com/slackapi/java-slack-sdk/blob/416ab0415983c42c88ff3b266858462edebf8c91/bolt/src/main/java/com/slack/api/bolt/App.javaquestion how to do it with deps edn
@stopachka (class MessageEvent)
should be just returns Class
, you actually want MessageEvent
which is the clojure equivalent of java's MessageEvent.class
eg.
(ins)user=> (class Number)
java.lang.Class
(ins)user=> Number
java.lang.Number
it's a good example of boilerplate elimination I think, what would Number be other than the class Number?
Having generated classes in a folder is fine, it should just be a folder inside the project
I'm wondering now whether there's any value other than nil
that returns something other than Class
from (comp class class)
probably nothing
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)
user=> (into #{} (map (comp class class))
[nil 1 Number "" String Double/NaN 'foo])
#{nil java.lang.Class}
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.
Woohoo! 🙂
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?
<groupId>javax.media</groupId>
<artifactId>jmf</artifactId>
<version>2.1.1e</version>
Clojure is "just" a dependency like:
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.10.3</version>
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...)
https://stackoverflow.com/questions/6819317/adding-dependencies-in-maven-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
ah, makes a loot of sense! Thanks @noisesmith, and clojure ftw!!
and it leads to the jar dialog
https://mvnrepository.com/artifact/org.clojure/clojure/1.10.2
has the option to download the jar file, I'm back on track
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? https://www.juxt.land/edge/docs/dev-guide.html#_starting_your_system
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~ ├── genfiles.properties ├── private │ ├── private.properties │ └── private.xml ├── project.properties ├── 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 🙂
barely
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 clojure.java.api.Clojure;
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/GeneratorServlet.java -Dnb.internal.action.name=debug.single -Ddirectory.deployment.supported=false -DforceRedeploy=false -Dbrowser.context=/home/jacekp/code/AAA-java/reportgenerator/src/java/servlets/GeneratorServlet.java -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
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.
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");
require.invoke("your.namespace");
IFn yourFunc = Clojure.var("your.namespace","your-func");
yourFunc.invoke(...);
do i put the hole project?
lidlcsvreport$ tree . ├── CHANGELOG.md ├── classes │ └── sal │ └── reports │ └── LIDL_Pesticide_Report.class ├── copy-java-classes ├── deps.edn ├── doc │ └── intro.md ├── LICENSE ├── lidlcsvreport.jar ├── pom.xml ├── README.md ├── http://README.org ├── 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 SEE!!!
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/javax.ws.rs-api-2.0.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/jboss-javaee.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/activation.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/jaxb-api.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/jbossws-native-jaxrpc.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/jbossws-native-jaxws-ext.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/jbossws-native-jaxws.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/jbossws-native-saaj.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/resolver.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/serializer.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/stax-api.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/xalan.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/endorsed/xercesImpl.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/concurrent.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/dom4j.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/getopt.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/javassist.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jaxb-impl.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jaxb-xjc.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-aop-asintegration-core.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-aop-asintegration-jmx.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-aop-asintegration-mc.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-aop-deployers.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-aop-jboss5.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-aop-mc-int.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-aop.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-bootstrap.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-classloader.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-classloading-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-classloading-vfs.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-classloading.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-common-core.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-dependency.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-client-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-client.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-core-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-core.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-impl.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-structure-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-vfs-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-deployers-vfs.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-j2se.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-jmx.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-kernel.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-logbridge.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-logging-jdk.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-logging-log4j.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-logging-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-logmanager.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-main.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-managed.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-mbeans.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-mdr.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-metatype.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-profileservice-spi.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-reflect.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-system-jmx.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-system.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-vfs.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/jboss-xml-binding.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/log4j-boot.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/osgi.core.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/trove.jar:/home/jacekp/apps/jboss-5.1.0.GA/lib/wstx.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/jbossws-native-jaxws-ext.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/ejb3-persistence.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/mail.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/el-api.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/jbossws-native-jaxrpc.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/jbossws-native-saaj.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/jbossws-native-jaxws.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/servlet-api.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/hibernate-entitymanager.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/jsp-api.jar:/home/jacekp/apps/jboss-5.1.0.GA/common/lib/jboss-jsr77.jar:/home/jacekp/apps/jboss-5.1.0.GA/server/default/deployers/ejb3.deployer/jboss-ejb3-deployer.jar:/home/jacekp/apps/jboss-5.1.0.GA/server/default/deployers/ejb3.deployer/jboss-ejb3-iiop.jar:/home/jacekp/apps/jboss-5.1.0.GA/server/default/deploy/jbossweb.sar/jsf-libs/jsf-api.jar:/home/jacekp/apps/jboss-5.1.0.GA/server/default/deploy/jbossweb.sar/jsf-libs/jsf-impl.jar:/home/jacekp/apps/jboss-5.1.0.GA/server/default/deploy/jbossweb.sar/jstl.jar 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.
.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/code/AAA-java/reportgenerator/src/clojure:/home/jacekp/netbeans-8.2r
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
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. https://borkdude.github.io/scittle/
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(Clojure.read("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
😮 clojurescript in the <script> tag!
big thanks to @seancorfield for his help 🙂
IFn require = Clojure.var("clojure.core", "require"); // this is a core function
Then
require.invoke(Clojure.read("example"));
IFn foo = Clojure.var("example", "foo"); // needs the ns for example/foo