Add AOT output dir to compile classpath - #1
Open
mogenson wants to merge 1 commit into
Open
Conversation
Prepend the ClojureCompileTask destination directory to the javaexec classpath so that classes generated by earlier-compiled namespaces are resolvable when a later namespace references them during its own compilation. Previously the output directory was set only as clojure.compile.path (the *destination* for generated .class files) and was not a classpath root. As a result, a namespace that (:import ...)s or directly constructs a gen-class'd class produced by a sibling namespace failed at AOT time with ClassNotFoundException — the sibling's .class file existed on disk but the compiler's DynamicClassLoader could not load it. This is common for apps with multiple gen-class'd Android entry points (e.g. a WallpaperService that constructs its gen-class'd Engine, or a Worker referenced by name). The workaround of resolving such classes reflectively via Class/forName is no longer necessary. Tested against a live-wallpaper app whose BingWallpaperService directly constructs its gen-class'd BingEngine: compilation now succeeds and all entry-point classes are emitted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ClojureCompileTasksets the Clojure compile output directory only via theclojure.compile.pathsystem property (the destination for generated.classfiles). It is not added to thejavaexecclasspath.Consequently, when a namespace
(:import ...)s or directly constructs agen-class'd class produced by a sibling namespace compiled earlier in the same task, the AOT compiler'sDynamicClassLoadercannot resolve it — the sibling's.classfile exists on disk but the output dir is not a classpath root. Compilation fails with:This is common for apps with multiple gen-class'd Android entry points — e.g. a
WallpaperServicethat constructs its gen-class'dEngine, or aWorkerreferenced by name. (Discovered while porting a live-wallpaper app whoseBingWallpaperServicebuilds itsBingEngine.)Fix
Prepend
destinationDirto thejavaexecclasspath. Classes generated by earlier-compiled namespaces are now on the classpath, so a later namespace can:import/ construct them directly. This removes the need to resolve such classes reflectively viaClass/forName.Test
Ported
com.binglivewallpaper.wallpaper-servicefrom a reflectiveClass/forNamelookup to a direct(BingEngine. this)constructor call. With this change,compileDebugClojuresucceeds (it previously threwClassNotFoundException: com.binglivewallpaper.BingEngine), all three gen-class'd entry-point classes are emitted, the fullassembleDebugAPK builds, and the unit tests pass.