I've been stalking Clojure for a while but now doing it professionally full-time (woo hoo!).I saw a Stuart Halloway tweet responding to someone who'd found it a "soul-crushing, miserable experience."I had a similar miserable experience and figured it was just me, but am now suspecting that's not the case. (Happy to be shown the light however.)Stuart H posted https://github.com/stuarthalloway/clojure-from-java to demonstrate the ease of Java consuming Clojure, but I find it far more important to be able to *compile* Java against Clojure interfaces not invoke it dynamically from Java....because dynamic invocation from Java is unwieldy to the point of it being a likely deal breaker for any Java shop. Dynamically loading classes and invoking methods.... c'mon, no one's going to ask their Java devs to do this.If Clojure doesn't have a good compile-time consumption story for Java consumers, I think that's a loss. (Even if it is just providing better docs or archetype/bootstrap examples in this regard.) Because otherwise Java code bases around the world could be eaten away by (compiled) Clojure from the inside out, giving Java dev teams enough time to be overtaken by the miracle that is Clojure.Inspired by Stuart's example, I was successful in putting together a quick build to achieve this ideal: https://github.com/atdixon/clojure-from-javaHowever, I have a few open questions:- when I tried to AOT only the public-facing clojure code that I needed to compile against, I found out at runtime that this wasn't going to work. Dynamic clojure code was loading my same types into DynamicClassLoader and when my statically-compiled, root-class-loaded code was getting executed the ClassCastExceptions of course were flying. So am I right to think that you have to AOT everything in order to do this right?- IDE support (for me, Cursive) "works" but is non-ideal; you have to manually compile the dependee/Clojure jar, then Cursive will let you execute Java code against the manually aot-compiled Clojure code- AOT producing generics/generic types doens't seem to be part of any of this... is this a lacuna in the Clojure AOT space, are there libs that can help here?This story ^^, if made easier, seems to me would boost Clojure adoption in Java/JVM shops.What am I missing?
This is great, Alex, thanks. (Sorry, I deleted from underneath you and reposted to fix the title before I saw your reply...)The latter option, writing interfaces and classes in Java and calling w/ the glue code is a great option.However one big motivator for people moving from Java to langs like Scala and Kotlin is being able to implement those bean/record types, eg, with such little fanfare & boilerplate (eg in Clojure, using defrecord is so concise).
And you can sometimes end up with a handful of these, so the 'glue code' isn't quite so small. Also gen-class and definterface I find similarly nice.
I wonder if there's a path to improve what you're calling option #2. Specifically the needing to AOT compile *everything*. It seems I should only have to AOT/precompile the surface area that my Java consumer wants to link with. At runtime perhaps there'd be some creative way to leave out the AOT classes (which would just have been used for static-time compiling) and when the JVM tries to load those classes some agent could interject and do the dynamic Clojure loading?
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/aejqMwraPk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/07753636-3414-481f-8836-763ca85675ce%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/aejqMwraPk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clo...@googlegroups.com.
<bean id="load_script_code"
class="clojure.lang.Compiler"
factory-method="loadFile">
<constructor-arg value="src/main/clojure/no-namespace-scripts/script-code.clj" />
</bean>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/aejqMwraPk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/c7ef72fe-b062-49b6-a3bb-5183e1a73d6c%40googlegroups.com.
Yes, the whole point of this approach is to define the interface in Java and the implementation in Clojure.
core.clj defines only names "getTimestamp" and "getName", but meaning of these names defined in Support.java. For example, that "getTimestamp" means result of a new java.util.Date.--
понедельник, 17 июня 2019 г., 23:35:30 UTC+3 пользователь Alex Miller написал:No, there is a bit of Java code just to load the Clojure
code, but then it’s Clojure after that (the entity record impl).
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/aejqMwraPk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clo...@googlegroups.com.
When you go with Option #2, you do not have to AOT everything, but AOT is transitive. So as you AOT the gen class, all code it requires and all code they in turn require will also be AOT. You can post-process the AOT when jaring, and only include the gen-class .class files in the Jar and not the dependencies, but that's more work.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/aejqMwraPk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/02a72bb0-9a6f-4574-9134-2d8983db8b81%40googlegroups.com.
In my experience, if you only keep the gen-class .class, and delete everything else, it all works without issues. If you are actually doing AOT, not for the purpose of gen-class, I wouldn't recommend deleting parts of it. From what I understand, the gen-class creates a class which will load the Clojure code in the static initialize, and look for the Clojure code as a resource on the classpath. This seems to work fine if it is only there as a .clj, it will perform just in time compilation and everything will work as normal.
Does anyone know of edge cases here? Or has experienced issues with this strategy?
The approach I’ve taken around :gen-class has been to ensure that the namespace offering the Java class via :gen-class has no static dependencies at all – instead it requires/resolves any other namespaces/symbols it needs at run time. That way AOT creates the .class you need but doesn’t spread to anything else.
This is even easier in Clojure 1.10 with the addition of requiring-resolve (which is also thread safe, unlike regular require right now).
But yeah, as Alex indicated, you need to be careful if you have an AOT’d entry point and downstream code is not AOT’d. Just one more “here be dragons” aspect of AOT, IMO.
Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/aejqMwraPk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/CY4PR2201MB11266042416A0BEFDBB233C6F4E70%40CY4PR2201MB1126.namprd22.prod.outlook.com.
But some code base are already using gen-class, and some people do use gen-class. Sometimes it works and it's easier then having to write Java and modify your build to also use javac and include Java built artifacts.
In those cases, the AOT is problematic, because it brings in dependencies, so if you package them as libraries, you get additional classes which can then conflict. So you need to find a way to only include the generated class and nothing else.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/aejqMwraPk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/bf3a22ec-efd0-4508-8e41-895a1329e328%40googlegroups.com.
Oh, you know me: I avoid AOT and gen-class at all costs _if I don’t have to use them_ 😊
Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood