module Java
Base module for all things Java.
Buildr runs along side a JVM, using either RJB or JRuby. The Java module allows you to access Java classes and create Java objects.
Java classes are accessed as static methods on the Java module, for example:
str = Java.java.lang.String.new('hai!') str.toUpperCase => 'HAI!' Java.java.lang.String.isInstance(str) => true Java.com.sun.tools.javac.Main.compile(args)
The classpath attribute allows Buildr to add JARs and directories to the classpath, for example, we use it to load Ant and various Ant tasks, code generators, test frameworks, and so forth.
When using an artifact specification, Buildr will automatically download and install the artifact before adding it to the classpath.
For example, Ant is loaded as follows:
Java.classpath << 'org.apache.ant:ant:jar:1.7.0'
Artifacts can only be downloaded after the Buildfile has loaded, giving it a chance to specify which remote repositories to use, so adding to classpath does not by itself load any libraries. You must call ::load before accessing any Java classes to give Buildr a chance to load the libraries specified in the classpath.
When building an extension, make sure to follow these rules:
-
Add to the classpath when the extension is loaded (i.e. in module or class definition), so the first call to ::load anywhere in the code will include the libraries you specify.
-
Call ::load once before accessing any Java classes, allowing Buildr to set up the classpath.
-
Only call ::load when invoked, otherwise you may end up loading the JVM with a partial classpath, or before all remote repositories are listed.
-
Check on a clean build with empty local repository.
Buildr runs along side a JVM, using either RJB or JRuby. The Java module allows you to access Java classes and create Java objects.
Java classes are accessed as static methods on the Java module, for example:
str = Java.java.lang.String.new('hai!') str.toUpperCase => 'HAI!' Java.java.lang.String.isInstance(str) => true Java.com.sun.tools.javac.Main.compile(args)
The classpath attribute allows Buildr to add JARs and directories to the classpath, for example, we use it to load Ant and various Ant tasks, code generators, test frameworks, and so forth.
When using an artifact specification, Buildr will automatically download and install the artifact before adding it to the classpath.
For example, Ant is loaded as follows:
Java.classpath << 'org.apache.ant:ant:jar:1.7.0'
Artifacts can only be downloaded after the Buildfile has loaded, giving it a chance to specify which remote repositories to use, so adding to classpath does not by itself load any libraries. You must call ::load before accessing any Java classes to give Buildr a chance to load the libraries specified in the classpath.
When building an extension, make sure to follow these rules:
-
Add to the classpath when the extension is loaded (i.e. in module or class definition), so the first call to ::load anywhere in the code will include the libraries you specify.
-
Call ::load once before accessing any Java classes, allowing Buildr to set up the classpath.
-
Only call ::load when invoked, otherwise you may end up loading the JVM with a partial classpath, or before all remote repositories are listed.
-
Check on a clean build with empty local repository.
Constants
- JRUBY_MIN_VERSION
This version is the minimal version Buildr will support. Any older version of JRuby will raise an exception.
Public Class Methods
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.
For example, Ant is loaded as follows:
Java.classpath << 'org.apache.ant:ant:jar:1.7.0'
# File lib/buildr/java/jruby.rb, line 74 def classpath @classpath ||= begin classpath = [] class << classpath def new_add(*args) warn 'Java is already loaded' if Java.loaded? send(:old_add, *args) end alias_method :old_add, :<< alias_method :<<, :new_add end classpath end 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.
# File lib/buildr/java/jruby.rb, line 109 def load return self if @loaded # 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.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)) } # 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 @loaded = true self end
Returns true if the JVM is loaded with all the libraries loaded on the classpath.
# File lib/buildr/java/jruby.rb, line 92 def loaded? @loaded end