Ma (petite) console Java
Quand j'ai commencé à développer en Java, parmi les choses qui me manquait le plus, une console, façon IRB, était dans le top 10. En effet, le problème avec les langages nécessitant une phase de compilation et que lorsque vous voulez tester rapidement un petit enchainement, vous avez l'impression de devoir sortir l'artillerie lourde. J'ai donc cherché s'il existait quelque chose pour m'aider, et je suis rapidement tombé sur BeanShell. Ce dernier, utilisé en ligne de commande, répond totalement à mon besoin. Cependant, je me suis également demandé si je ne pourrais pas mettre en place ma propre solution.
Je me suis donc tourné vers ce que je connais et j'ai essayé de mettre en place une solution à base de JRuby et java-inline. Le résultat n'est pas parfait, mais il répond au besoin de base.
Voici un example d'utilisation :
$ export CLASSPATH=commons-io-2.0.1.jar
$ ruby jconsole.rb
jConsole with Java 10.7
> \help
\import [PACKAGE] : Import package PACKAGE or display imports if no package given
\unimport [PACKAGE] : Remove package PACKAGE import
\run : Set auto-run on/off
\help : Display help
\quit : Quit jConsole
CLASSPATH set to : commons-io-2.0.1.jar
> \run
run OFF
> \import org.apache.commons.io.FileUtils
> \import java.io.File
> File temp = FileUtils.getTempDirectory();
> System.out.println("TEMP FILE = "+temp.getPath());
> \run
run ON
TEMP FILE = /var/folders/h3/x2n5fwvd2q955wyr1y8_87kr0000gn/T
>
Et voici le code de la chose :
#!jruby
unless RUBY_PLATFORM === "java"
puts "jConsole only works with jRuby"
puts "For more informations, see http://www.jruby.org/"
exit 1
end
require 'readline'
require 'rubygems'
begin
require 'term/ansicolor'
rescue
puts "please install term/ansicolor : "
puts " [sudo] gem install term-ansicolor"
exit 1
end
require 'inline'
begin
require 'java_inline'
rescue
puts "please install java-inline : "
puts " [sudo] gem install java-inline"
exit 1
end
require 'java'
class JConsole
class Runner
def initialize
clean
end
def clean
@complete_source = nil
@imports = []
@java_klass = nil
end
def unimport(packages)
@imports -= packages
end
def import(packages)
if packages.size == 0
@imports.each { |i| puts "\t#{i}" }
else
@imports += packages
end
end
def uniline(data)
methodName = create_uniline_method(data)
compile
@java_klass.send(methodName.to_sym)
end
private
def compile
source = @complete_source
imp = @imports
jKlass = Class.new do
inline :Java do |builder|
imp.each { |i|
builder.import i
}
builder.java source
end
end
@java_klass = jKlass.new
end
def create_uniline_method(data)
methodName = "x"+Time.now.to_i.to_s
@complete_source = "
public static void #{methodName}() {
#{data}
}
"
methodName
end
end
def initialize
@runner = Runner.new
@runner.uniline("System.out.println(\"jConsole with Java \" + System.getProperty(\"os.version\"));")
@run = true
ENV['CLASSPATH'] = "." if ENV['CLASSPATH'].nil?
end
def jrun?(data)
[["(", ")"], ["{", "}"], ["[", "]"]].each do |e|
return false if data.count(e[0]) != data.count(e[1])
end
return true
end
def command(args)
action = args.shift.to_sym
run = false
case action
when :import
@runner.import args
when :unimport
@runner.unimport args
when :run
@run = !@run
print Term::ANSIColor.yellow, "run #{ @run ? 'ON' : 'OFF' }\n", Term::ANSIColor.clear
run = true
when :help
help
when :quit
exit 0
else
print Term::ANSIColor.red, "Command `\\#{action}' undefined! Try \\help\n", Term::ANSIColor.clear
end
return run
end
def help
print Term::ANSIColor.blue
puts "\\import [PACKAGE] : Import package PACKAGE or display imports if no package given"
puts "\\unimport [PACKAGE] : Remove package PACKAGE import"
puts "\\run : Set auto-run on/off"
puts ""
puts "\\help : Display help"
puts "\\quit : Quit jConsole"
puts ""
puts "CLASSPATH set to : "+ENV['CLASSPATH']
print Term::ANSIColor.clear
end
def run
kode = ""
print Term::ANSIColor.green
while line = Readline.readline( "> ", true )
run = true
if line =~ /^\\/
run = command line.chomp.gsub(/^\\/, "").split(" ")
line = ""
end
print Term::ANSIColor.clear
if run
unless jrun?(kode+line) && @run
kode += line
else
@runner.uniline(kode+line.chomp)
kode = ""
end
end
print Term::ANSIColor.green
end
print Term::ANSIColor.clear
end
end
JConsole.new.run
A moins que vous soyez une peu téméraire, vous pouvez parfaitement utiliser jConsole. Cependant, BeanShell est une solution plus raisonnable ;)