<< Back to previous view

[CLJS-2422] Remove build dependence on Clojure release zip file Created: 27/Nov/17  Updated: 01/Dec/17  Resolved: 01/Dec/17

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Alex Miller Assignee: David Nolen
Resolution: Completed Votes: 2
Labels: build

Attachments: Text File cljs-clojure-jar.patch    
Patch: Code
Approval: Accepted


Currently the ClojureScript build depends on the Clojure release zip file, but only uses it to extract the Clojure jar file. As part of changes in 1.9, we are going to stop building and releasing this zip file.

The attached patch updates the build to just directly download and use the jar file instead of the zip file which contains it.

Without this patch, the ClojureScript build will stop working when we remove the release zip.

Comment by David Nolen [ 01/Dec/17 3:24 PM ]

fixed https://github.com/clojure/clojurescript/commit/11265fdf19e7bd33001fd9698a0f86aa46ef9c95

[CLJS-2194] cljs.util/relative-name bug Created: 08/Jul/17  Updated: 09/Jul/17  Resolved: 09/Jul/17

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.854
Fix Version/s: 1.9.854

Type: Defect Priority: Major
Reporter: António Nuno Monteiro Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: build

Attachments: Text File CLJS-2194.patch    
Patch: Code and Test
Approval: Accepted


cljs.util/relative-name is still not quite right for paths that end with trailing slashes

Comment by David Nolen [ 09/Jul/17 8:09 AM ]

fixed https://github.com/clojure/clojurescript/commit/b88d290f95f6ac9bc7040ceaf8cfb3a57e6b9935

[CLJS-2152] "is not a relative path" exception thrown when `:libs` directory is provided. Created: 02/Jul/17  Updated: 08/Jul/17  Resolved: 08/Jul/17

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 1.9.671
Fix Version/s: 1.9.854

Type: Defect Priority: Blocker
Reporter: Bruce Hauman Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: build


Attachments: Text File CLJS-2152.patch    
Patch: Code and Test
Approval: Accepted


This problem shows up in this simple case:

In the compiler config set :libs to ["js_libs"]

Create a GCL file in "js_libs"


tabby.hello = function() {return "hello there from tabby";};

In the main cljs file require the GCL lib:

(ns example.core
  (:require [tabby]))

This should produce the following stacktrace:

java.lang.IllegalArgumentException: /tabby.js is not a relative path
 at clojure.java.io$as_relative_path.invokeStatic (io.clj:414)
    clojure.java.io$file.invokeStatic (io.clj:426)
    clojure.java.io$file.invoke (io.clj:418)
    cljs.closure$write_javascript.invokeStatic (closure.clj:1658)
    cljs.closure$write_javascript.invoke (closure.clj:1651)
    cljs.closure$source_on_disk.invokeStatic (closure.clj:1697)
    cljs.closure$source_on_disk.invoke (closure.clj:1692)
    cljs.closure$output_unoptimized$fn__13956.invoke (closure.clj:1735)
    clojure.core$map$fn__4785.invoke (core.clj:2646)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:521)
    clojure.core$seq__4357.invokeStatic (core.clj:137)
    clojure.core$filter$fn__4812.invoke (core.clj:2700)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:521)
    clojure.core$seq__4357.invokeStatic (core.clj:137)
    clojure.core$map$fn__4785.invoke (core.clj:2637)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.next (RT.java:688)
    clojure.core$next__4341.invokeStatic (core.clj:64)
    clojure.core$str$fn__4419.invoke (core.clj:546)
    clojure.core$str.invokeStatic (core.clj:544)
    clojure.core$str.doInvoke (core.clj:533)
    clojure.lang.RestFn.applyTo (RestFn.java:139)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.core$apply.invoke (core.clj:641)
    cljs.closure$deps_file.invokeStatic (closure.clj:1433)
    cljs.closure$deps_file.invoke (closure.clj:1430)
    cljs.closure$output_deps_file.invokeStatic (closure.clj:1453)
    cljs.closure$output_deps_file.invoke (closure.clj:1452)
    cljs.closure$output_unoptimized.invokeStatic (closure.clj:1743)
    cljs.closure$output_unoptimized.doInvoke (closure.clj:1726)
    clojure.lang.RestFn.applyTo (RestFn.java:139)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    cljs.closure$build.invokeStatic (closure.clj:2352)
    cljs.closure$build.invoke (closure.clj:2236)
    cljs.build.api$build.invokeStatic (api.clj:202)
    cljs.build.api$build.invoke (api.clj:189)

Comment by Francis Avila [ 02/Jul/17 8:35 PM ]

I ran in to this issue on a large, complex project which I was upgrading from 1.8.51 to a few commits short of 1.9.655. However, I never created a minimal case. Some more information I can add:

  1. This is a regression since 1.8.51.
  2. I experienced this on a project where :libs and :src were the same. (Cljs and goog-compatible js were intermingled in same source root.) I thought that might have been relevant but it looks like it is not.
  3. The length of the goog-provided namespace does not matter. (One segment and many-segment both fail.)
  4. A workaround is to include the full path to the goog file in :libs. For example, {{:libs ["js_libs/tabby.js"] }} will not fail. This is the workaround I used in my project.
Comment by David Nolen [ 08/Jul/17 9:21 AM ]

The patch must supply a test.

Comment by António Nuno Monteiro [ 08/Jul/17 2:14 PM ]

Patch attached.

Comment by Martin Klepsch [ 08/Jul/17 3:44 PM ]

Tested the patch with cljsjs/incremental-dom. Working as advertised 👍

FWIW, in contrast to Francis' observations I thought this only affected :libs with single segment goog.provide names. After stumbling into this with incremental-dom I tried to reproduce it with openlayers but I couldn't reproduce the issue there.

Comment by David Nolen [ 08/Jul/17 4:48 PM ]

fixed https://github.com/clojure/clojurescript/commit/df1351362e8456d5242793d20c56321392f07917

[CLJS-1437] Recompile dependents broken when files are not inside one directory Created: 30/Aug/15  Updated: 03/Nov/15  Resolved: 03/Nov/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.145
Fix Version/s: 1.7.228

Type: Defect Priority: Major
Reporter: Juho Teperi Assignee: David Nolen
Resolution: Completed Votes: 1
Labels: build

Attachments: Text File cljs-1437-8.patch    


When a file is changed files dependent on that file are marked for recompile. This doesn't seem to work when the changed file is not in the directory which is passed to build and the directory where dependent namespace is.

Looks like this caused by how build and compile-file work:

  • Build calls -compile -> compile-dir -> compile-root which sorts the files in dependency order and calls -compile for the files in dependency order
    • core ns is compiled
  • Build calls add-depedencies -> add-dependencies -> get-compiled-cljs -> -compile -> compile-file
    • test ns is compiled, core ns is marked as dependent on test ns but as core ns is already compiled this doesn't matter

I believe this effectively breaks :recompile-dependents in cases all cases but one where all the sources are inside one directory. In multiple directory case order of directories passed to cljs.build.api/inputs affects the order on which compile is called so it's possible that some dependent namespaces are compiled before namespaces they depend on are compiled.

Original problem was that added tests were not picked up by run-tests but I have since reproduced this without cljs.test.

The minimal way to reproduce this needs two namespaces, where one depends on another. To display that the dependent namespace is not recompiled, it will print some compile time metadata from the another namespace.


(ns hello.core
  (:require hello-world.test))


(println (:foo (meta #'hello.test/a)))


(ns hello.test)

(def ^{:foo :bar} a "foobar")

To build:

(require '[cljs.build.api :refer [build]])

(def opts {:main "hello.core"
           :output-to "out/main.js"
           :output-dir "out"
           :optimizations :none
           :verbose true})

(defn broken []
  (build "src" opts))

(defn working []
  " Note: ordering of the dirs matters
  (build (inputs "src2" "src" opts)))

To trigger the problem, the metadata needs to be changed after running the build once. Changing test ns doesn't cause core ns to recompiled and changing the metadata doesn't have any effect to println on core ns.

Comment by Juho Teperi [ 02/Sep/15 5:55 PM ]

First version for review.

Still missing support for finding sources for any build source parameter. Previously this was provided through Compilable interface but that doesn't make sense anymore as we don't want to compile them but find the namespaces.

Function naming could use some thinking.

This includes minimally changed alternative build function: build-new. I think future improvements to recompile-dependents would be limited to compile-sources where it would be possible to mark all dependent namespaces for recompile.

Comment by Juho Teperi [ 09/Sep/15 2:02 PM ]

Separate patches for deps bits and another for alternative build implementation.

Comment by Juho Teperi [ 22/Sep/15 1:05 PM ]

A patch contains the new functions.
B modifies build to use new pipeline.


To support different kind of source parameters, I added new method to Compilable protocol which only finds the source files in given source (dir, file, url...). There is still problem with supporting giving the source as list or vector, as I'm not sure if it's possible to create IJavaScript map from already read source.

Compile-file is still doing the recompile-dependents logic which is not optimal, but it's probably best to implement those changes separately.

Comment by Juho Teperi [ 22/Sep/15 1:14 PM ]

I noticed I forgot to update build function to use new -find-sources method. Fixed in 3a and 3b patches.

Comment by David Nolen [ 22/Sep/15 10:23 PM ]

Please remove all patches that don't just implement the new pipeline. Thanks! It just makes figuring out what patch to look at that much more complicated.

Comment by Juho Teperi [ 23/Sep/15 12:38 PM ]

Removed old patches.

Comment by Juho Teperi [ 29/Sep/15 2:57 PM ]

I noticed I had accidentally committed automatic version changes in second patch. Fixed now.

Comment by Juho Teperi [ 19/Oct/15 2:30 PM ]

I noticed that build still contained some old code which caused it to compile most sources twice.

Updated B patch.

Comment by Juho Teperi [ 19/Oct/15 2:43 PM ]

Combined the patches.

Comment by David Nolen [ 26/Oct/15 4:57 PM ]

The patch needs to be rebased on master also please actually squash the patch into a single commit thanks.

Comment by Juho Teperi [ 27/Oct/15 12:39 PM ]

Rebased and squashed.

Also, I think I found solution for cljs.js' dependency on cljs.core$macros. (Fixes https://github.com/mneise/cljs-1437-test)

Comment by Juho Teperi [ 29/Oct/15 2:38 PM ]

Updated patch to fix problem with recompile dependents. Fixed by adding cljs.compiler/inputs binding to cljs.closure/compiler-sources. This is needed so that cljs.compiler/compile-file can see the namespace data from current run and use that to check the ns-dependents.

Comment by Juho Teperi [ 01/Nov/15 2:33 AM ]

Updated the patch with a change to cljs.analyzer/locate-src. This fixes problem in a case where a file being compiled depends on a file which is not available on classpath and is not yet analyzed.

Comment by David Nolen [ 03/Nov/15 6:04 PM ]

Fixed https://github.com/clojure/clojurescript/commit/409d1eca4fcf776be1f7b28f759d6f36f7a83ec8

[CLJ-2276] Add build for standalone jar Created: 27/Nov/17  Updated: 27/Nov/17  Resolved: 27/Nov/17

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.9
Fix Version/s: Release 1.9

Type: Enhancement Priority: Major
Reporter: Alex Miller Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: build

Attachments: Text File standalone-3.patch    
Patch: Code
Approval: Ok


Until Clojure 1.9, the local ant build produced a standalone executable jar. This is no longer the case due to the external libs (spec.alpha and core.specs.alpha).

The attached patch adds a new Maven profile and ant target for a "local" build that is self-contained and includes the spec jars.

# Maven:
mvn -Plocal -Dmaven.test.skip=true package

# Ant:
ant local

# Run:
java -jar clojure.jar

[CLJ-2231] Remove dep lib exclusions Created: 30/Aug/17  Updated: 10/Nov/17

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: Release 1.9
Fix Version/s: Release 1.10

Type: Defect Priority: Major
Reporter: Alex Miller Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: build

Attachments: Text File remove-exclusions.patch    
Patch: Code
Approval: Vetted


Originally, the spec.alpha and core.specs.alpha lib deps pulled in an older version of Clojure itself as dependencies and they were excluded by Clojure.

These libs have been altered to rely on Clojure, etc as provided scope dependencies instead, so Clojure no longer needs to exclude them (as they are no longer transitive deps).

Note: before applying this patch, the pom must be updated to rely on a version of spec.alpha with these changes (but we haven't released one yet).

Patch: remove-exclusions.patch

[CLJ-2132] Maven pom requires artifact signing to install locally Created: 23/Mar/17  Updated: 20/Apr/17  Resolved: 20/Apr/17

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.9
Fix Version/s: Release 1.9

Type: Enhancement Priority: Major
Reporter: Alex Miller Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: build, regression

Attachments: Text File clj-2132.patch    
Patch: Code
Approval: Ok


The recent pom changes inadvertently made artifact signing a requirement for locally installing a Clojure build via:

mvn clean install

The attached patch moves the GPG plugin back into a profile (named "sign").

[CLJ-2113] Update Clojure maven for latest on CI server Created: 16/Feb/17  Updated: 14/Mar/17  Resolved: 14/Mar/17

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: Release 1.9

Type: Enhancement Priority: Critical
Reporter: Alex Miller Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: build

Attachments: Text File mvn3.patch    
Patch: Code
Approval: Ok


Update maven build infrastructure to stop using oss-parent and use updated Maven 3 and sonatype plugins (similar to other changes made recently in all contrib projects).

  • Removed oss-parent parent pom. This has been deprecated for years and is no longer recommended for use.
  • Add snapshot repo (was previously pulled in via oss-parent)
  • maven-compiler-plugin - update to latest version
  • maven-release-plugin - update to latest version
  • add nexus-staging-maven-plugin - current recommended plugin for releases to maven central, replaces most of the maven-release-plugin's work (old version of this previously in oss-parent)
  • add maven-gpg-plugin for signing (previously in oss-parent)
  • remove old release profile which was activated by oss-parent pom

Patch: mvn3.patch

It's difficult to test this completely outside the context of actually building and deploying snapshots and releases but the changes are very similar to those made for all contrib projects recently.

[CLJ-1834] Support for test matrix build of direct linking on / off Created: 26/Oct/15  Updated: 27/Oct/15  Resolved: 27/Oct/15

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.8
Fix Version/s: Release 1.8

Type: Enhancement Priority: Major
Reporter: Alex Miller Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: build

Attachments: Text File clj-1834-2.patch     Text File clj-1834-3.patch     Text File clj-1834.patch    
Patch: Code
Approval: Ok


Enable build box test matrix build of direct linking on and off.

Modified build to do the following:

  • Maven build - add user property "directlinking" with default value "true"
  • Maven build - add two profiles: "direct" and "nodirect" which force this property to either "true" or "false"
  • Ant build - defines new property "directlinking"
  • Ant build - inherits this property value from Maven automatically
  • Ant build - echoes the setting of the property during test compilation so you can tell which is activated
  • Ant build - compiles and runs tests with clojure.compiler.direct-linking set to the value of ${directlinking}

The Maven build can be invoked with one of these as follows:

mvn clean test -Ptest-direct
mvn clean test -Ptest-no-direct

The Hudson clojure-test-matrix will have a new axis with values "test-direct" and "test-no-direct" and a modified command line that will set the profile with -P based on the axis value.

Patch: clj-1834-3.patch

Comment by Alex Miller [ 26/Oct/15 5:10 PM ]

I may have broken the default ant build behavior with this patch, need to check on that still but taking a break for now...

Comment by Alex Miller [ 27/Oct/15 9:03 AM ]

Ant behavior fixed in -2 patch

[CLJ-1509] Some clojure namespaces not AOT-compiled and included in the clojure jar Created: 20/Aug/14  Updated: 12/Jan/16

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: Release 1.6
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Alex Miller Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: build

Patch: Code


There is a list of namespaces to AOT in build.xml and several namespaces are missing from that list, thus no .class files for those namespaces are created or included in the standard clojure jar file as part of the build.

Missing namespaces include:

  • clojure.core.reducers
  • clojure.instant
  • clojure.parallel
  • clojure.uuid

Proposal: Attached patch sorts the ns list alphabetically (for easier maintenance) and adds clojure.instant and clojure.uuid to the compiled namespaces. clojure.parallel is deprecated and requires the JSR-166 jar so was not included (perhaps it's a separate ticket to remove this). clojure.core.reducers uses a compile-time check to choose the fork/join packages to use so cannot be compiled early.

Patch: clj-1509.diff

Screened by:

Comment by Alex Miller [ 20/Aug/14 1:06 PM ]

Looking at this a bit further, clojure.core.reducers uses the compile-if macro to determine what version of fork/join is available so AOT-compiling this namespace would fix that decision at build time rather than runtime, so it cannot be included.

[CLJ-1268] Require Java 1.6 as minimum for Clojure Created: 28/Sep/13  Updated: 25/Oct/13  Resolved: 25/Oct/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.6
Fix Version/s: Release 1.6

Type: Enhancement Priority: Blocker
Reporter: Alex Miller Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: build

Attachments: Text File clj-1268.patch    
Patch: Code
Approval: Ok


In Clojure 1.6, we plan to move to JDK 1.6 as the minimum JDK.

Patch: clj-1268.patch

This patch changes the build configurations for both Maven and Ant to assume JDK 1.6 as the "source" and "target" runtimes.

Configuration changes will be necessary on Hudson. We already build Clojure and contrib libraries on JDK 1.6 by default, but we will need to remove matrix test builds for JDK 1.5. See for example clojure-test-matrix and data.csv-test-matrix – coordinate with Stuart Sierra for this change.

Comment by Stuart Sierra [ 04/Oct/13 8:45 AM ]


I have verified that both the Ant and Maven builds still work (running on JDK 1.7) and that the output .class files contain the bytecode header for JDK 1.6.

[CLJ-1161] sources jar has bad versions.properties resource Created: 11/Feb/13  Updated: 16/Dec/15  Resolved: 16/Dec/15

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4, Release 1.5
Fix Version/s: Release 1.8

Type: Defect Priority: Minor
Reporter: Steve Miner Assignee: Alex Miller
Resolution: Completed Votes: 18
Labels: build

Attachments: Text File 0001-CLJ-1161-Remove-version.properties-from-sources-JAR.patch     Text File clj-1161.patch    
Patch: Code
Approval: Ok


The "sources" jar (at least since Clojure 1.4 and including 1.5 RC) has a bad version.properties file in it. The resource clojure/version.properties is literally:


The regular Clojure jar has the correct version string in that resource.

I came across a problem when I was experimenting with the sources jar (as used by IDEs). I naively added the sources jar to my classpath, and Clojure died on start up. The bad clojure/versions.properties file was found first, which led to a parse error as the clojure version was being set.

Cause: We configure the maven-source-plugin plugin in our pom.xml to exclude the clojure/version.properties file, and this works for SNAPSHOT builds but NOT for release builds. One difference during release builds is that we are running different goals and profiles, which seems to cause the configuration for the maven-source-plugin to be configured as defined in the oss-parent pom (https://repo1.maven.org/maven2/org/sonatype/oss/oss-parent/7/oss-parent-7.pom) instead of our configuration, and so the exclusion is not done.

Solution: If we use the same execution id as used in the oss-parent for the maven-source-plugin configuration, our configuration will override the parent pom configuration and the exclusion will take effect, both in snapshot builds and in release builds. The patch makes this change, just using "attach-sources" as the execution id.

Patch: clj-1161.patch

I was able to reproduce the bad source jar locally by running a command like:

mvn --batch-mode -Dtag=whatever release:prepare -DreleaseVersion=1.8.0-xyz -DdevelopmentVersion=1.8.1-SNAPSHOT

Note that this will generate some local files AND make a local tag and commit! So be careful testing locally if you have commit access (Stu!). You can undo that commit with `git reset HEAD~1` and the tag with `git tag -d whatever`. Before the patch, you should see:

$ jar xf target/clojure-1.8.0-xyz-sources.jar clojure/version.properties
$ cat clojure/version.properties
version=${version}   # this is the bad stuff

After, you should see that target/clojure-1.8.0-xyz-sources.jar does not contain clojure/version.properties at all:

$ jar tf target/clojure-1.8.0-xyz-sources.jar | grep version
# nothing found

Comment by Steve Miner [ 11/Feb/13 10:04 AM ]

Notes from the dev mailing list:

The "sources" JAR is generated by another Maven plugin, configured here:

The simplest solution might be to just exclude the file from the sources jar. It looks like maven-source-plugin has an excludes option which would do the trick:


Comment by Jeff Valk [ 21/Apr/14 8:20 AM ]

This issue is marked closed, but I'm still seeing it: the clojure-1.6.0-sources.jar, clojure-1.5.1-sources.jar, etc on Maven Central still contain the bad version.properties files. More specifically, it looks like the fix has been applied to builds in the SNAPSHOTS repository, but not to RELEASES.

Fix applied: https://oss.sonatype.org/content/repositories/snapshots/org/clojure/clojure/
Not fixed: https://oss.sonatype.org/content/repositories/releases/org/clojure/clojure/

Comment by Alex Miller [ 24/Apr/14 4:15 PM ]

Not sure what's needed here, but marking incomplete.

Comment by Jeff Valk [ 25/Apr/14 11:13 AM ]

Would a fix for this update existing sources jars (1.5.1, 1.6.0, etc) on Central? Or would any fix have to wait on the next Clojure release?

Comment by Alex Miller [ 25/Apr/14 12:37 PM ]

For all the same reasons that mutable state is undesirable, changing an existing release jar in the central Maven repository is also undesirable. While it's not technically impossible, we will not update existing releases and this will need to wait for the next. I've looked at this problem a little and I do not yet know enough to know how to fix it or why it even varies between snapshot and release. Help welcome!

In which tool do you see a resulting problem from this?

Comment by Jeff Valk [ 25/Apr/14 11:56 PM ]

Despite the way I phrased the question, I'd hoped that would be the answer. It's the right policy.

Unfortunately, this issue leaves the released sources jars essentially unusable from a tools standpoint. CIDER now has source code navigation from stacktraces – you can jump into both Clojure and Java function definitions from the error/trace. For the latter, the sources jar (for Clojure or any other Java library) needs to be on the classpath as a dev dependency. There's more host interop support in the works for CIDER too ("embrace the host platform"), but not being able to add a dependency on a stable Clojure sources jar presents a wrinkle.

Are the official Clojure releases built by Hudson? The Hudson build right before the 1.6.0 release (#532) and the one right after (#534) both show the exclusion fix, as does the git clojure-1.6.0 tag, which when I check out and build from source, is fine. The Hudson builds with release tags (e.g. 1.6 = #533, 1.6-RC1 = #512, etc), though, don't show any artifacts other than a pom.xml. This would seem to make it rather hard to audit builds...am I missing something?

Comment by Michael Griffiths [ 11/Dec/15 3:43 PM ]

This still seems to be the case for the 1.7 and 1.8 sources jars; version.properties contains the above in both https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0/clojure-1.7.0-sources.jar and https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0-RC3/clojure-1.8.0-RC3-sources.jar

Comment by Alex Miller [ 11/Dec/15 9:47 PM ]

Thanks for bumping this - I keep meaning to look at it.

Comment by Bozhidar Batsov [ 15/Dec/15 1:38 AM ]

I really hope this is finally going to be resolved. It has caused us quite a lot of pain in CIDER.

Comment by Alex Miller [ 15/Dec/15 8:57 AM ]

While the final fix was simple, it took many painful hours of Maven detective work to track it down. We are on track to get it in the next RC.

Comment by Bozhidar Batsov [ 15/Dec/15 2:53 PM ]

Fantastic news!

[CLJ-250] debug builds Created: 27/Jan/10  Updated: 23/Oct/13

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: Release 1.2
Fix Version/s: Backlog

Type: Enhancement Priority: Minor
Reporter: Stuart Halloway Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: build

Approval: Vetted
Waiting On: Rich Hickey


This ticket includes two patches:

  1. a patch to set assert when clojure.lang.RT loads, based on the presence of system property clojure.debug
  2. expand error messages in assert to include local-bindings</code> (a new macro which wraps the implicit <code>&env)

Things to consider before approving these patches:

  1. should there be an easy Clojure-level way to query if debug is enabled? (checking assert isn't the same, as debug should eventually drive other features)
  2. assertions will now be off by default – this is a change!
  3. is the addition of the name local-bindings to clojure.core cool?

Comment by Assembla Importer [ 24/Aug/10 6:05 AM ]

Converted from http://www.assembla.com/spaces/clojure/tickets/250
add-clojure-debug-flag.patch - https://www.assembla.com/spaces/clojure/documents/aUWn50c64r35E-eJe5aVNr/download/aUWn50c64r35E-eJe5aVNr
assert-report-locals.patch - https://www.assembla.com/spaces/clojure/documents/aUWqLSc64r35E-eJe5aVNr/download/aUWqLSc64r35E-eJe5aVNr

Comment by Stuart Halloway [ 07/Dec/10 8:23 PM ]

Ignore the old patches. Considering the following implementation, please review and then move ticket to waiting on Stu:

  1. RT will check system property "clojure.debug", default to false
  2. property will set the root binding for the current *assert*, plus a new *debug* flag. (Debug builds can and will drive other things than just asserts.)
  3. does Compile.java need to push *assert* or *debug* as thread local bindings, or can they be root-bound only when compiling clojure?
  4. will add *debug* binding to clojure.main/with-bindings. Anywhere else?
  5. build.xml should not have to change – system properties will flow through (and build.xml may not be around much longer anyway)
  6. once we agree on the approach, I will ping maven plugin and lein owners so that they flow the setting through
  7. better assertion messages will be a separate ticket
  8. what is the interaction between *debug* and *unchecked-math*? Change checks to (and *unchecked-math* (not *debug*))}?
Comment by Rich Hickey [ 08/Dec/10 11:00 AM ]

#3 - root bound only
#4 - should not be in with-bindings for same reason as #3 - we don't want people to set! *debug* nor *assert*
#8 - yes, wrapping that in a helper fn

#6 - my biggest reservation is that this isn't yet informed by maven best practices

Comment by Stuart Sierra [ 08/Dec/10 2:09 PM ]

System properties can be passed through Maven, so I do not anticipate this being a problem.

However, I would prefer *assert* to remain true by default.

Comment by Chas Emerick [ 09/Dec/10 7:19 AM ]

SS is correct about this approach not posing any issue for Maven. In addition, the build could easily be set up to always emit two jars, one "normal", one "debug".

I'd suggest that, while clojure.debug might have broad effect, additional properties should be available to provide fine-grained control over each of the additional "debug"-related parameterizations that might become available in the future.

I'd like to raise a couple of potentially tangential concerns (after now thinking about assertions for a bit in the above context), some or all of which may simply be a result of my lack of understanding in various areas.

Looking at where assert is used in core.clj (only two places AFAICT: validating arguments to derive and checking pre- and post-conditions in fn), it would seem unwise to make it false by default. i.e. non-Named values would be able to get into hierarchies, and pre- and post-conditions would simply be ignored.

It's my understanding that assertions (talking here of the JVM construct, from which Clojure reuses AssertionError) should not be used to validate arguments to public API functions, or used to validate any aspect of a function's normal operation (i.e. "where not to use assertions"). That would imply that derive should throw IllegalArugmentException when necessary, and fn pre- and post-conditions should perhaps throw IllegalStateException – or, in any case, something other than AssertionError via assert. This would match up far better with most functions in core using assert-args rather than assert, the former throwing IllegalArgumentException rather than AssertionError.

That leads me to the question: is assert (and *assert*) intended to be a Clojure construct, or a quasi-interop form?

If the former, then it can roughly have whatever semantics we want, but then it seems like it should not be throwing AssertionError.

If the latter, then AssertionError is appropriate on the JVM, but then we need to take care that assertions can be enabled and disabled at runtime (without having to switch around different builds of Clojure), ideally using the host-defined switches (e.g. -ea and friends) and likely not anything like *assert*. I don't know if this is possible or practical at this point (I presume this would require nontrivial compiler changes).

Hopefully the above is not water under the bridge at this point. Thank you in advance for your forbearance.

Comment by Rich Hickey [ 09/Dec/10 8:08 AM ]

Thanks for the useful input Chas. Nothing is concluded yet. I think we should step back and look at the objective here, before moving forward with a solution. Being a dynamic language, there are many things we might want to validate about our programs, where the cost of checking is something we are unwilling to pay in production.

Being a macro, assert has the nice property that, should *assert* not be true during compilation, it generates nil, no conditional test at all. Thus right now it is more like static conditional compilation.

Java assert does have runtime toggle-ability, via -ea as you say. I haven't looked at the bytecode generated for Java asserts, but it might be possible for Clojure assert to do something similar, if the runtime overhead is negligible. It is quite likely that HotSpot has special code for eliding the assertion bytecode given a single check of some flag. I'm just not sure that flag is Class.desiredAssertionStatus.

Whether this turns into changes in assert or pre/post conditions, best practices etc is orthogonal and derived. Currently we don't have a facility to run without the checks. We need to choose between making them disappear during compilation (debug build) or runtime (track -ea) or both. Then we can look at how that is reflected in assert/pre-post and re-examine existing use of both. The "where not to use assertions" doc deals with them categorically, but in not considering their cost, seems unrealistic IMO.

I'd appreciate it if someone could look into how assert is generated and optimized by Java itself.

Comment by Chas Emerick [ 09/Dec/10 5:04 PM ]

Bytecode issues continue to be above my pay grade, unfortunately…

A few additional thoughts in response that you may or may not be juggling already:

assert being a macro makes total sense for what it's doing. Trouble is, "compile-time" is a tricky concept in Clojure: there's code-loading-time, AOT-compile-time, and transitively-AOT-compile-time. Given that, it's entirely possible for an application deployed to a production environment that contains a patchwork of code or no code produced by assert usages in various libraries and namespaces depending upon when those libs and ns' were loaded, AOT-compiled, or their dependents AOT-compiled, and the value of *assert* at each of those times. Of course, this is the case for all such macros whose results are dependent upon context-dependent state (I think this was a big issue with clojure.contrib.logging, making it only usable with log4j for a while).

What's really attractive about the JVM assertion mechanism is that it can be parameterized for a given runtime on a per-package basis, if desired. Reimplementing that concept so that assert can be *ns*-sensitive seems like it'd be straightforward, but the compile-time complexity already mentioned remains, and the idea of having two independently-controlled assertion facilities doesn't sound fun.

I know nearly nothing about the CLR, but it would appear that it doesn't provide for anything like runtime-controllable assertions.

Comment by Stuart Halloway [ 29/Dec/10 3:17 PM ]

The best (dated) evidence I could find says that the compiler sets a special class static final field $assertionsDisabled based on the return of desiredAssertionStatus. HotSpot doesn't do anything special with this, dead code elimination simply makes it go away. The code indeed compiles this way:

11: getstatic #6; //Field $assertionsDisabled:Z
14: ifne 33
17: lload_1
18: lconst_0
19: lcmp
20: ifeq 33
23: new #7; //class java/lang/AssertionError
26: dup
27: ldc #8; //String X should be zero
29: invokespecial #9; //Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
32: athrow

Even if we were 100% sure that assertion removal was total, I would still vote for a separate Clojure-level switch, for the following reasons:

  1. I have a real and pressing need to disable some assertions, and I don't need the Java interop at all. Arguably others will be in the same boat.
  2. there will be multiple debugging facilities over time, and having a top-level debug switch is convenient for Clojure users.
  3. Java dis/enabling via command line flags is still possible as a separate feature. We could add this later as a (small) breaking change to our assert, or have a separate java-assert interop form. I am on the fence about which way to go here.
  4. I believe it is perfectly fine to throw an AssertionError from a non-Java-assertion-form. We don't believe in a world of a static exception hierarchy, and an assertion in production is a critical failure no matter what you call it. Even Scala does it http://daily-scala.blogspot.com/2010/03/assert-require-assume.html

Rich: awaiting your blessing to move forward on this.

Comment by Rich Hickey [ 07/Jan/11 9:42 AM ]

The compiler sets $assertionsDisabled when, in static init code? Is there special support in the classloader for it? Is there a link to the best dated evidence you found?

Comment by Stuart Halloway [ 07/Jan/11 9:51 AM ]
  1. Yes, in static init code
  2. There is no special support in the classloader, per Brian Goetz (private correspondence) last week. But dead code elimination is great: "The run-time cost of disabled assertions should indeed be zero for compiled code"
Comment by Stuart Halloway [ 07/Jan/11 9:57 AM ]

Link: Google "java assert shirazi". (Not posting link because I can't tell in 10 secs whether it includes my session information.)

Comment by Alexander Kiel [ 14/Mar/13 1:28 PM ]

Is there anything new on this issue? I also look for a convenient way to disable assertions in production.

Comment by Michał Łopuszyński [ 11/Oct/13 4:21 AM ]

I am also interested in any news on this issue.
Convenient way to enable/disable assertions at runtime (preferably via -ea/-da options) would be a great feature!

Comment by Michał Łopuszyński [ 23/Oct/13 3:12 AM ]

Btw. there is a library for runtime-toggable assertions available via clojars
This helped me a great deal.

Generated at Thu Jan 18 12:23:46 CST 2018 using JIRA 4.4#649-r158309.