# class Rake::JavaExtensionTask

### Attributes

classpath[RW]
debug[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 38
    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 28
    def init(name = nil, gem_spec = nil)
      super
      @source_pattern = '**/*.java'
      @classpath      = nil
      @java_compiling = nil
      @debug          = false
      @source_version = '1.6'
      @target_version = '1.6'
    end

java_compiling(&block) click to toggle source

    # File lib/rake/javaextensiontask.rb, line 24
    def java_compiling(&block)
      @java_compiling = block if block_given?
    end

platform() click to toggle source

    # File lib/rake/javaextensiontask.rb, line 20
    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 45
        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_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 131
    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 205
    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_extdirs_arg() click to toggle source

Discover Java Extension Directories and build an extdirs argument

    # File lib/rake/javaextensiontask.rb, line 190
    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