lib/buildr/java/jruby.rb in vic-buildr-1.3.1 vs lib/buildr/java/jruby.rb in vic-buildr-1.3.3

- old
+ new

@@ -54,10 +54,14 @@ # 3. Only call Java.load when invoked, otherwise you may end up loading the JVM # with a partial classpath, or before all remote repositories are listed. # 4. Check on a clean build with empty local repository. module Java + # Since we already have a JVM loaded, we can use it to guess where JAVA_HOME is. + # We set JAVA_HOME early so we can use it without calling Java.load first. + ENV['JAVA_HOME'] ||= java.lang.System.getProperty("java.home") + class << self # Returns the classpath, an array listing directories, JAR files and # artifacts. Use when loading the extension to add any additional # libraries used by that extension. @@ -65,32 +69,46 @@ # For example, Ant is loaded as follows: # Java.classpath << 'org.apache.ant:ant:jar:1.7.0' def classpath @classpath ||= [] end + + # Most platforms requires tools.jar to be on the classpath, tools.jar contains the + # Java compiler (OS X and AIX are two exceptions we know about, may be more). + # Guess where tools.jar is from JAVA_HOME, which hopefully points to the JDK, + # but maybe the JRE. Return nil if not found. + def tools_jar #:nodoc: + @tools_jar ||= ['lib/tools.jar', '../lib/tools.jar'].map { |path| File.expand_path(path, ENV['JAVA_HOME']) }. + find { |path| File.exist?(path) } + end # Loads the JVM and all the libraries listed on the classpath. Call this # method before accessing any Java class, but only call it from methods # used in the build, giving the Buildfile a chance to load all extensions # that append to the classpath and specify which remote repositories to use. def load return self if @loaded - cp = Buildr.artifacts(classpath).map(&:to_s).each { |path| file(path).invoke } - #cp ||= java.lang.System.getProperty('java.class.path').split(':').compact - # Use system ClassLoader to add classpath. + + # Adding jars to the jruby's $CLASSPATH should be the correct thing, however it + # seems like some tools require their jars on system class loader (javadoc, junit, etc) + # cp.each { |path| $CLASSPATH << path } + + # Use system ClassLoader to add classpath sysloader = java.lang.ClassLoader.getSystemClassLoader add_url_method = java.lang.Class.forName('java.net.URLClassLoader'). - getDeclaredMethod('addURL', [java.net.URL].to_java(java.lang.Class)) + getDeclaredMethod('addURL', [java.net.URL.java_class].to_java(java.lang.Class)) add_url_method.setAccessible(true) add_path = lambda { |path| add_url_method.invoke(sysloader, [java.io.File.new(path).toURI.toURL].to_java(java.net.URL)) } - # Include tools (compiler, Javadoc, etc) for all platforms except OS/X. - unless Config::CONFIG['host_os'] =~ /darwin/i - home = ENV['JAVA_HOME'] or fail 'Are we forgetting something? JAVA_HOME not set.' - tools = File.expand_path('lib/tools.jar', home) - raise "Missing #{tools}, perhaps your JAVA_HOME is not correclty set" unless File.file?(tools) - add_path[tools] + + # Most platforms requires tools.jar to be on the classpath. + add_path[tools_jar] if tools_jar + + classpath.map! { |path| Proc === path ? path.call : path } + Buildr.artifacts(classpath).map(&:to_s).each do |path| + file(path).invoke + add_path[path] end - cp.each { |path| add_path[path] } + @loaded = true self end end