class Rake::JavaExtensionTask

Attributes

classpath[RW]
debug[RW]
encoding[RW]
source_version[RW]

Provide source compatibility with specified release

target_version[RW]

Generate class files for specific VM version

Public Instance Methods

define() click to toggle source
Calls superclass method Rake::BaseExtensionTask#define
# File lib/rake/javaextensiontask.rb, line 41
def define
  super

  define_java_platform_tasks
end
init(name = nil, gem_spec = nil) click to toggle source
Calls superclass method Rake::BaseExtensionTask#init
# File lib/rake/javaextensiontask.rb, line 30
def init(name = nil, gem_spec = nil)
  super
  @source_pattern = '**/*.java'
  @classpath      = nil
  @debug          = false
  @source_version = '1.6'
  @target_version = '1.6'
  @encoding       = nil
  @java_compiling = nil
end
java_compiling(&block) click to toggle source
# File lib/rake/javaextensiontask.rb, line 26
def java_compiling(&block)
  @java_compiling = block if block_given?
end
platform() click to toggle source
# File lib/rake/javaextensiontask.rb, line 22
def platform
  @platform ||= 'java'
end

Private Instance Methods

define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION) click to toggle source
# File lib/rake/javaextensiontask.rb, line 48
    def define_compile_tasks(for_platform = nil, ruby_ver = RUBY_VERSION)
      # platform usage
      platf = for_platform || platform

      # lib_path
      lib_path = lib_dir

      # tmp_path
      tmp_path = "#{@tmp_dir}/#{platf}/#{@name}"

      # cleanup and clobbering
      CLEAN.include(tmp_path)
      CLOBBER.include("#{lib_path}/#{binary(platf)}")
      CLOBBER.include("#{@tmp_dir}")

      # directories we need
      directory tmp_path
      directory lib_dir

      # copy binary from temporary location to final lib
      # tmp/extension_name/extension_name.{so,bundle} => lib/
      task "copy:#{@name}:#{platf}" => [lib_path, "#{tmp_path}/#{binary(platf)}"] do
        install "#{tmp_path}/#{binary(platf)}", "#{lib_path}/#{binary(platf)}"
      end

      file "#{tmp_path}/#{binary(platf)}" => "#{tmp_path}/.build" do

        class_files = FileList["#{tmp_path}/**/*.class"].
          gsub("#{tmp_path}/", '')

        # avoid environment variable expansion using backslash
        class_files.gsub!('$', '\$') unless windows?

        args = class_files.map { |path|
          ["-C #{tmp_path}", path]
        }.flatten

        sh "jar cf #{tmp_path}/#{binary(platf)} #{args.join(' ')}"
      end

      file "#{tmp_path}/.build" => [tmp_path] + source_files do
        not_jruby_compile_msg = <<-EOF
WARNING: You're cross-compiling a binary extension for JRuby, but are using
another interpreter. If your Java classpath or extension dir settings are not
correctly detected, then either check the appropriate environment variables or
execute the Rake compilation task using the JRuby interpreter.
(e.g. `jruby -S rake compile:java`)
        EOF
        warn_once(not_jruby_compile_msg) unless defined?(JRUBY_VERSION)

        classpath_arg = java_classpath_arg(@classpath)
        debug_arg     = @debug ? '-g' : ''

        sh "javac #{java_encoding_arg} #{java_extdirs_arg} -target #{@target_version} -source #{@source_version} -Xlint:unchecked #{debug_arg} #{classpath_arg} -d #{tmp_path} #{source_files.join(' ')}"

        # Checkpoint file
        touch "#{tmp_path}/.build"
      end

      # compile tasks
      unless Rake::Task.task_defined?('compile') then
        desc "Compile all the extensions"
        task "compile"
      end

      # compile:name
      unless Rake::Task.task_defined?("compile:#{@name}") then
        desc "Compile #{@name}"
        task "compile:#{@name}"
      end

      # Allow segmented compilation by platform (open door for 'cross compile')
      task "compile:#{@name}:#{platf}" => ["copy:#{@name}:#{platf}"]
      task "compile:#{platf}" => ["compile:#{@name}:#{platf}"]

      # Only add this extension to the compile chain if current
      # platform matches the indicated one.
      if platf == RUBY_PLATFORM then
        # ensure file is always copied
        file "#{lib_path}/#{binary(platf)}" => ["copy:#{name}:#{platf}"]

        task "compile:#{@name}" => ["compile:#{@name}:#{platf}"]
        task "compile" => ["compile:#{platf}"]
      end
    end
define_java_platform_tasks() click to toggle source
# File lib/rake/javaextensiontask.rb, line 134
def define_java_platform_tasks
  # lib_path
  lib_path = lib_dir

  if @gem_spec && !Rake::Task.task_defined?("java:#{@gem_spec.name}")
    task "java:#{@gem_spec.name}" do |t|
      # FIXME: workaround Gem::Specification limitation around cache_file:
      # http://github.com/rubygems/rubygems/issues/78
      spec = gem_spec.dup
      spec.instance_variable_set(:"@cache_file", nil) if spec.respond_to?(:cache_file)

      # adjust to specified platform
      spec.platform = Gem::Platform.new('java')

      # clear the extensions defined in the specs
      spec.extensions.clear

      # add the binaries that this task depends on
      ext_files = []

      # go through native prerequisites and grab the real extension files from there
      t.prerequisites.each do |ext|
        ext_files << ext
      end

      # include the files in the gem specification
      spec.files += ext_files

      # expose gem specification for customization
      if @java_compiling
        @java_compiling.call(spec)
      end

      # Generate a package for this gem
      Gem::PackageTask.new(spec) do |pkg|
        pkg.need_zip = false
        pkg.need_tar = false
      end
    end

    # add binaries to the dependency chain
    task "java:#{@gem_spec.name}" => ["#{lib_path}/#{binary(platform)}"]

    # ensure the extension get copied
    unless Rake::Task.task_defined?("#{lib_path}/#{binary(platform)}") then
      file "#{lib_path}/#{binary(platform)}" => ["copy:#{name}:#{platform}"]
    end

    task 'java' => ["java:#{@gem_spec.name}"]
  end

  task 'java' do
    task 'compile' => 'compile:java'
  end
end
java_classpath_arg(*args) click to toggle source

Discover the Java/JRuby classpath and build a classpath argument

@params

*args:: Additional classpath arguments to append

Copied verbatim from the ActiveRecord-JDBC project. There are a small myriad of ways to discover the Java classpath correctly.

# File lib/rake/javaextensiontask.rb, line 215
def java_classpath_arg(*args)
  jruby_cpath = nil
  if RUBY_PLATFORM =~ /java/
    begin
      cpath  = Java::java.lang.System.getProperty('java.class.path').split(File::PATH_SEPARATOR)
      cpath += Java::java.lang.System.getProperty('sun.boot.class.path').split(File::PATH_SEPARATOR)
      jruby_cpath = cpath.compact.join(File::PATH_SEPARATOR)
    rescue => e
    end
  end

  # jruby_cpath might not be present from Java-9 onwards as it removes
  # sun.boot.class.path. Check if JRUBY_HOME is set as env variable and try
  # to find jruby.jar under JRUBY_HOME
  unless jruby_cpath
    jruby_home = ENV['JRUBY_HOME']
    if jruby_home
      candidate = File.join(jruby_home, 'lib', 'jruby.jar')
      jruby_cpath = candidate if File.exist?(candidate)
    end
  end

  # JRUBY_HOME is not necessarily set in JRuby-9.x
  # Find the libdir from RbConfig::CONFIG and find jruby.jar under the
  # found lib path
  unless jruby_cpath
    libdir = RbConfig::CONFIG['libdir']
    if libdir.start_with?("uri:classloader:")
      raise 'Cannot build with jruby-complete from Java 9 onwards'
    end
    candidate = File.join(libdir, "jruby.jar")
    jruby_cpath = candidate if File.exist?(candidate)
  end

  unless jruby_cpath
    raise "Could not find jruby.jar. Please set JRUBY_HOME or use jruby in rvm"
  end

  jruby_cpath += File::PATH_SEPARATOR + args.join(File::PATH_SEPARATOR) unless args.empty?
  jruby_cpath ? "-cp \"#{jruby_cpath}\"" : ""
end
java_encoding_arg() click to toggle source

Build an encoding argument

# File lib/rake/javaextensiontask.rb, line 202
def java_encoding_arg
  @encoding.nil? ? "" : "-encoding \"#{@encoding}\""
end
java_extdirs_arg() click to toggle source

Discover Java Extension Directories and build an extdirs argument

# File lib/rake/javaextensiontask.rb, line 193
def java_extdirs_arg
  extdirs = Java::java.lang.System.getProperty('java.ext.dirs') rescue nil
  extdirs = ENV['JAVA_EXT_DIR'] unless extdirs
  java_extdir = extdirs.nil? ? "" : "-extdirs \"#{extdirs}\""
end