dundalek/closh

Compilation of the Java version

dundalek opened this issue · 8 comments

The goal is to compile closh into a single jar binary.

I have created a pkg-java branch which tries to use cambada for packaging.

I use a following command:

clj -R:cambada -m cambada.uberjar -m closh.zero.frontend.rebel-readline`

However, I get errors resolving some packages. It seems that maven repository for org.sonatype.oss is missing. I did google around but could not figure out how to fix the dependencies.

Here is the full error output:

Cleaning target
Creating target/classes
  Compiling closh.zero.builtin
  Compiling closh.zero.compiler
  Compiling closh.zero.core
  Compiling closh.zero.env
  Compiling closh.zero.frontend.clojure-main-repl
  Compiling closh.zero.frontend.rebel-readline
  Compiling closh.zero.macros
  Compiling closh.zero.parser
  Compiling closh.zero.pipeline
  Compiling closh.zero.platform.io
  Compiling closh.zero.platform.process
  Compiling closh.zero.reader
  Compiling closh.zero.service.completion
  Compiling closh.zero.util
Creating target/closh-1.0.0-SNAPSHOT.jar
Updating pom.xml
Skipping coordinate: {:git/url https://github.com/dundalek/tools.reader, :sha 64a792b8ab6f774cab01c64d143c306ea81c84ff}
Exception in thread "main" org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for org.jline:jline-terminal-jansi:jar:3.5.1
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:323)
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:192)
	at org.eclipse.aether.internal.impl.DefaultRepositorySystem.readArtifactDescriptor(DefaultRepositorySystem.java:253)
	at clojure.tools.deps.alpha.extensions.maven$eval2624$fn__2626.invoke(maven.clj:79)
	at clojure.lang.MultiFn.invoke(MultiFn.java:243)
	at clojure.tools.deps.alpha$expand_deps.invokeStatic(alpha.clj:170)
	at clojure.tools.deps.alpha$expand_deps.invoke(alpha.clj:152)
	at clojure.tools.deps.alpha$resolve_deps.invokeStatic(alpha.clj:215)
	at clojure.tools.deps.alpha$resolve_deps.invoke(alpha.clj:197)
	at cambada.uberjar$get_dep_jars.invokeStatic(uberjar.clj:109)
	at cambada.uberjar$get_dep_jars.invoke(uberjar.clj:107)
	at cambada.uberjar$apply_BANG_.invokeStatic(uberjar.clj:132)
	at cambada.uberjar$apply_BANG_.invoke(uberjar.clj:129)
	at cambada.cli$runner.invokeStatic(cli.clj:120)
	at cambada.cli$runner.invoke(cli.clj:115)
	at cambada.uberjar$_main.invokeStatic(uberjar.clj:142)
	at cambada.uberjar$_main.doInvoke(uberjar.clj:140)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
Caused by: org.apache.maven.model.resolution.UnresolvableModelException: Could not find artifact org.sonatype.oss:oss-parent:pom:9
	at org.apache.maven.repository.internal.DefaultModelResolver.resolveModel(DefaultModelResolver.java:178)
	at org.apache.maven.repository.internal.DefaultModelResolver.resolveModel(DefaultModelResolver.java:224)
	at org.apache.maven.model.building.DefaultModelBuilder.readParentExternally(DefaultModelBuilder.java:1051)
	at org.apache.maven.model.building.DefaultModelBuilder.readParent(DefaultModelBuilder.java:829)
	at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:331)
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:314)
	... 26 more
Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not find artifact org.sonatype.oss:oss-parent:pom:9
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:422)
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:224)
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:201)
	at org.apache.maven.repository.internal.DefaultModelResolver.resolveModel(DefaultModelResolver.java:174)
	... 31 more
Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact org.sonatype.oss:oss-parent:pom:9
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:412)
	... 34 more

I tried it also with clj.native-image but it gives an error. There are some dynamic class loading issues:

error: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Unsupported method java.lang.ClassLoader.defineClass(String, byte[], int, int) is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class
To diagnose the issue, you can add the option -H:+ReportUnsupportedElementsAtRuntime. The unsupported element is then reported at run time when it is accessed the first time.
Detailed message:
Error: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Unsupported method java.lang.ClassLoader.defineClass(String, byte[], int, int) is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class
To diagnose the issue, you can add the option -H:+ReportUnsupportedElementsAtRuntime. The unsupported element is then reported at run time when it is accessed the first time.
Trace: 
	at parsing clojure.lang.DynamicClassLoader.defineClass(DynamicClassLoader.java:46)
Call path from entry point to clojure.lang.DynamicClassLoader.defineClass(String, byte[], Object): 
	at clojure.lang.DynamicClassLoader.defineClass(DynamicClassLoader.java:45)
	at clojure.core$get_proxy_class.invokeStatic(core_proxy.clj:288)
	at clojure.core$get_proxy_class.doInvoke(core_proxy.clj:276)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at rebel.main(Unknown Source)
	at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:177)
	at com.oracle.svm.core.code.CEntryPointCallStubs.com_002eoracle_002esvm_002ecore_002eJavaMainWrapper_002erun_0028int_002corg_002egraalvm_002enativeimage_002ec_002etype_002eCCharPointerPointer_0029(generated:0)

@dundalek Not sure whether it's related, but I've discovered that the clj command doesn't support deps projects that still need to compile namespaces. You would have to compile it with something else (e.g. boot) and then add the target dir (or whatever you have configured to the :paths entry).

When I found out about this I discovered that boot is way more convenient to use with deps.edn, e.g.

boot -d seancorfield/boot-tools-deps:0.4.5 deps repl

Hope this helps.

Btw, @dundalek I would like to support the development of the JVM version, but not sure where I could be helpful exactly. Would some financial support from my company (maybe in the grand scheme of things just symbolic) be of interest to you?

@jeroenvandijk Thanks for the support. I would love to eventually have some kind of sustainable patreon/opencollective funding so that I could allocate bigger chunk of my time to closh. But I feel the project is not popular enough so donations would be marginal at this point. So my plan is to work on some additional features I have in roadmap to generate some more excitement first.

To give better idea about the progress I wrote down remaining steps in the original JVM issue.

So at this point the best help would probably be to try things out, give any kind of feedback and report bugs.

Actually if you have time it would be cool to try to set up the build with boot as you suggested. I am more familiar with lein (which won't work since the deps integration does not support git hashes which are needed for the custom tools.reader). So I will likely spend time on other things first than getting more familiar with boot.

@dundalek Thanks for your reply. I'll look into building with boot. I'm just starting with boot as well, so this might take some time.

Regarding my use case for closh, my wish is to have all our company's AWS infrastructure use closh as main shell, and also use it as replacement for bash scripts. The amount of bash code we have, and therefore the required knowledge to work with it, is scary (to me). I'll send you a pm regarding potential sponsoring.

I've tried boot here #90 . I think there is an aot problem with the forked reader (see the tracktrace in the issue)

Done, next release will include a downloadable uberjar 🎉