79
I Use This!
High Activity

News

Analyzed about 24 hours ago. based on code collected 2 days ago.
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
Hello again!As you may know, I've been working part-time on a new language called Duby. Duby looks like Ruby, since it co-opts the JRuby parser, and includes some of the features of the Ruby language like optional arguments and closures. But Duby is ... [More] not Ruby; it's statically typed, compiles to "native" code (JVM bytecode, for example) before running, and does not have any built-in library of its own (preferring to just use what's available on a given runtime). Here's a quick sample of Duby code:class Foo def initialize(hello:String) puts 'constructor' @hello = hello end def hello(name:String) puts "#{@hello}, #{name}" endendFoo.new('Hiya').hello('Duby')This post is not going to be an overview of the Duby language; I'll get that together soon, once I take stock of where the language stands as far as features go. Instead, this "getting started" post will show how you can grab the Duby repository and start playing with it right now.First you need to pull down three resources: Duby itself, BiteScript (the Ruby DSL I use to generate JVM bytecode), and a JRuby 1.5 snapshot:~/projects/tmp ➔ git clone git://github.com/headius/duby.gitInitialized empty Git repository in /Users/headius/projects/tmp/duby/.git/remote: Counting objects: 2810, done.remote: Compressing objects: 100% (1291/1291), done.remote: Total 2810 (delta 1690), reused 2509 (delta 1447)Receiving objects: 100% (2810/2810), 10.64 MiB | 722 KiB/s, done.Resolving deltas: 100% (1690/1690), done.~/projects/tmp ➔ git clone git://github.com/headius/bitescript.gitInitialized empty Git repository in /Users/headius/projects/tmp/bitescript/.git/remote: Counting objects: 470, done.remote: Compressing objects: 100% (404/404), done.remote: Total 470 (delta 166), reused 313 (delta 57)Receiving objects: 100% (470/470), 93.56 KiB, done.Resolving deltas: 100% (166/166), done.~/projects/tmp ➔ curl http://ci.jruby.org/snapshots/jruby-bin-1.5.0.dev.tar.gz | tar xz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 11.3M 100 11.3M 0 0 353k 0 0:00:32 0:00:32 --:--:-- 262k~/projects/tmp ➔ lsbitescript duby jruby-1.5.0.dev~/projects/tmp ➔ mv jruby-1.5.0.dev/ jrubyOnce you have these three pieces in place, Duby can now be run. It's easiest to put the JRuby snapshot in PATH, but you can just run it directly too:~/projects/tmp ➔ cd duby~/projects/tmp/duby ➔ ../jruby/bin/jruby bin/duby -e "puts 'hello'"hello~/projects/tmp/duby ➔ ../jruby/bin/jruby bin/dubyc -e "puts 'hello'"~/projects/tmp/duby ➔ java DashEhelloFinally, you may want to create a "complete" Duby jar that includes Duby, BiteScript, JRuby, and Java classes for command-line or Ant task usage. Using JRuby 1.5's Ant integration, the Duby Rakefile can produce that for you:~/projects/tmp/duby ➔ ../jruby/bin/jruby -S rake jar:complete(in /Users/headius/projects/tmp/duby)mkdir -p buildCompiling Ruby sourcesGenerating Java class DubyCommand to DubyCommand.javajavac -d build -cp ../jruby/lib/jruby.jar:. DubyCommand.javaCompiling Duby sourcesmkdir -p distBuilding jar: /Users/headius/projects/tmp/duby/dist/duby.jarmkdir -p distBuilding jar: /Users/headius/projects/tmp/duby/dist/duby-complete.jar~/projects/tmp/duby ➔ java -jar dist/duby-complete.jar run -e 'puts "Duby is Awesome!"'Duby is Awesome!Hopefully we'll soon have duby.jar, duby-complete.jar, and a new Duby gem released, but this is a quick way to get involved.I'll get back to you with a post on the Duby language itself Real Soon Now!Update: I have also uploaded a snapshot duby-complete.jar (which includes both the Main-Class for jar execution and the simple Ant task org.jruby.duby.ant.Compiler) on the Duby Github downloads page. Have fun! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
Hello again!As you may know, I've been working part-time on a new language called Duby. Duby looks like Ruby, since it co-opts the JRuby parser, and includes some of the features of the Ruby language like optional arguments and closures. But Duby is ... [More] not Ruby; it's statically typed, compiles to "native" code (JVM bytecode, for example) before running, and does not have any built-in library of its own (preferring to just use what's available on a given runtime). Here's a quick sample of Duby code:class Foo def initialize(hello:String) puts 'constructor' @hello = hello end def hello(name:String) puts "#{@hello}, #{name}" endendFoo.new('Hiya').hello('Duby')This post is not going to be an overview of the Duby language; I'll get that together soon, once I take stock of where the language stands as far as features go. Instead, this "getting started" post will show how you can grab the Duby repository and start playing with it right now.First you need to pull down three resources: Duby itself, BiteScript (the Ruby DSL I use to generate JVM bytecode), and a JRuby 1.5 snapshot:~/projects/tmp ➔ git clone git://github.com/headius/duby.gitInitialized empty Git repository in /Users/headius/projects/tmp/duby/.git/remote: Counting objects: 2810, done.remote: Compressing objects: 100% (1291/1291), done.remote: Total 2810 (delta 1690), reused 2509 (delta 1447)Receiving objects: 100% (2810/2810), 10.64 MiB | 722 KiB/s, done.Resolving deltas: 100% (1690/1690), done.~/projects/tmp ➔ git clone git://github.com/headius/bitescript.gitInitialized empty Git repository in /Users/headius/projects/tmp/bitescript/.git/remote: Counting objects: 470, done.remote: Compressing objects: 100% (404/404), done.remote: Total 470 (delta 166), reused 313 (delta 57)Receiving objects: 100% (470/470), 93.56 KiB, done.Resolving deltas: 100% (166/166), done.~/projects/tmp ➔ curl http://ci.jruby.org/snapshots/jruby-bin-1.5.0.dev.tar.gz | tar xz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 11.3M 100 11.3M 0 0 353k 0 0:00:32 0:00:32 --:--:-- 262k~/projects/tmp ➔ lsbitescript duby jruby-1.5.0.dev~/projects/tmp ➔ mv jruby-1.5.0.dev/ jrubyOnce you have these three pieces in place, Duby can now be run. It's easiest to put the JRuby snapshot in PATH, but you can just run it directly too:~/projects/tmp ➔ cd duby~/projects/tmp/duby ➔ ../jruby/bin/jruby bin/duby -e "puts 'hello'"hello~/projects/tmp/duby ➔ ../jruby/bin/jruby bin/dubyc -e "puts 'hello'"~/projects/tmp/duby ➔ java DashEhelloFinally, you may want to create a "complete" Duby jar that includes Duby, BiteScript, JRuby, and Java classes for command-line or Ant task usage. Using JRuby 1.5's Ant integration, the Duby Rakefile can produce that for you:~/projects/tmp/duby ➔ ../jruby/bin/jruby -S rake jar:complete(in /Users/headius/projects/tmp/duby)mkdir -p buildCompiling Ruby sourcesGenerating Java class DubyCommand to DubyCommand.javajavac -d build -cp ../jruby/lib/jruby.jar:. DubyCommand.javaCompiling Duby sourcesmkdir -p distBuilding jar: /Users/headius/projects/tmp/duby/dist/duby.jarmkdir -p distBuilding jar: /Users/headius/projects/tmp/duby/dist/duby-complete.jar~/projects/tmp/duby ➔ java -jar dist/duby-complete.jar run -e 'puts "Duby is Awesome!"'Duby is Awesome!Hopefully we'll soon have duby.jar, duby-complete.jar, and a new Duby gem released, but this is a quick way to get involved.I'll get back to you with a post on the Duby language itself Real Soon Now!Update: I have also uploaded a snapshot duby-complete.jar (which includes both the Main-Class for jar execution and the simple Ant task org.jruby.duby.ant.Compiler) on the Duby Github downloads page. Have fun! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
Hello again!As you may know, I've been working part-time on a new language called Duby. Duby looks like Ruby, since it co-opts the JRuby parser, and includes some of the features of the Ruby language like optional arguments and closures. But Duby is ... [More] not Ruby; it's statically typed, compiles to "native" code (JVM bytecode, for example) before running, and does not have any built-in library of its own (preferring to just use what's available on a given runtime). Here's a quick sample of Duby code:class Foo def initialize(hello:String) puts 'constructor' @hello = hello end def hello(name:String) puts "#{@hello}, #{name}" endendFoo.new('Hiya').hello('Duby')This post is not going to be an overview of the Duby language; I'll get that together soon, once I take stock of where the language stands as far as features go. Instead, this "getting started" post will show how you can grab the Duby repository and start playing with it right now.First you need to pull down three resources: Duby itself, BiteScript (the Ruby DSL I use to generate JVM bytecode), and a JRuby 1.5 snapshot:~/projects/tmp ➔ git clone git://github.com/headius/duby.gitInitialized empty Git repository in /Users/headius/projects/tmp/duby/.git/remote: Counting objects: 2810, done.remote: Compressing objects: 100% (1291/1291), done.remote: Total 2810 (delta 1690), reused 2509 (delta 1447)Receiving objects: 100% (2810/2810), 10.64 MiB | 722 KiB/s, done.Resolving deltas: 100% (1690/1690), done.~/projects/tmp ➔ git clone git://github.com/headius/bitescript.gitInitialized empty Git repository in /Users/headius/projects/tmp/bitescript/.git/remote: Counting objects: 470, done.remote: Compressing objects: 100% (404/404), done.remote: Total 470 (delta 166), reused 313 (delta 57)Receiving objects: 100% (470/470), 93.56 KiB, done.Resolving deltas: 100% (166/166), done.~/projects/tmp ➔ curl http://ci.jruby.org/snapshots/jruby-bin-1.5.0.dev.tar.gz | tar xz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 11.3M 100 11.3M 0 0 353k 0 0:00:32 0:00:32 --:--:-- 262k~/projects/tmp ➔ lsbitescript duby jruby-1.5.0.dev~/projects/tmp ➔ mv jruby-1.5.0.dev/ jrubyOnce you have these three pieces in place, Duby can now be run. It's easiest to put the JRuby snapshot in PATH, but you can just run it directly too:~/projects/tmp ➔ cd duby~/projects/tmp/duby ➔ ../jruby/bin/jruby bin/duby -e "puts 'hello'"hello~/projects/tmp/duby ➔ ../jruby/bin/jruby bin/dubyc -e "puts 'hello'"~/projects/tmp/duby ➔ java DashEhelloFinally, you may want to create a "complete" Duby jar that includes Duby, BiteScript, JRuby, and Java classes for command-line or Ant task usage. Using JRuby 1.5's Ant integration, the Duby Rakefile can produce that for you:~/projects/tmp/duby ➔ ../jruby/bin/jruby -S rake jar:complete(in /Users/headius/projects/tmp/duby)mkdir -p buildCompiling Ruby sourcesGenerating Java class DubyCommand to DubyCommand.javajavac -d build -cp ../jruby/lib/jruby.jar:. DubyCommand.javaCompiling Duby sourcesmkdir -p distBuilding jar: /Users/headius/projects/tmp/duby/dist/duby.jarmkdir -p distBuilding jar: /Users/headius/projects/tmp/duby/dist/duby-complete.jar~/projects/tmp/duby ➔ java -jar dist/duby-complete.jar run -e 'puts "Duby is Awesome!"'Duby is Awesome!Hopefully we'll soon have duby.jar, duby-complete.jar, and a new Duby gem released, but this is a quick way to get involved.I'll get back to you with a post on the Duby language itself Real Soon Now!Update: I have also uploaded a snapshot duby-complete.jar (which includes both the Main-Class for jar execution and the simple Ant task org.jruby.duby.ant.Compiler) on the Duby Github downloads page. Have fun! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
JRuby 1.5 will be released soon, and one of the coolest new features is the integration of Ant support into Rake, the Ruby build tool. Tom Enebo wrote an article on the Rake/Ant integration for the Engine Yard blog, which has lots of examples of how ... [More] to start migrating to Rake without leaving Ant behind. I'm not going to cover all that here.I've been using the Rake/Ant stuff for a few weeks now, first for my "weakling" RubyGem which adds a queue-supporting WeakRef to JRuby, and now for cleaning up Duby's build process. Along the way, I've realized I really never want to write Ant scripts again; they're so much nicer in Rake, and I have all of Ruby and Ant available to me.One thing Ant still needs help with is dependency resolution. Many people make the leap to Maven, and let it handle all the nuts and bolts. But that only works if you really buy into the Maven way of life...a problem if you're like me and you live in a lot of hybrid worlds where the Maven way doesn't necessarily fit. So many folks are turning to Apache Ivy to get dependency management in their builds without using Maven.Today I thought I'd translate the simple "no-install" Ivy example build (warning, XML) to Rake, to see how easy it would be. The results are pretty slick.First we need to construct the equivalent to the "download-ivy" and "install-ivy" ant tasks. I chose to put that in a Rake namespace, like this:namespace :ivy do ivy_install_version = '2.0.0-beta1' ivy_jar_dir = './ivy' ivy_jar_file = "#{ivy_jar_dir}/ivy.jar" task :download do mkdir_p ivy_jar_dir ant.get :src => "http://repo1.maven.org/maven2/org/apache/ivy/ivy/#{ivy_install_version}/ivy-#{ivy_install_version}.jar", :dest => ivy_jar_file, :usetimestamp => true end task :install => :download do ant.path :id => 'ivy.lib.path' do fileset :dir => ivy_jar_dir, :includes => '*.jar' end ant.taskdef :resource => "org/apache/ivy/ant/antlib.xml", #:uri => "antlib:org.apache.ivy.ant", :classpathref => "ivy.lib.path" endendNotice that instead of using Ant properties, I've just used Ruby variables for the Ivy install version, dir, and file. I've also removed the "uri" element to ant.taskdef because I'm not sure if we have an equivalent for that in Rake yet (note to self: figure out if we have an equivalent for that).With these two tasks, we can now fetch ivy and install it for the remainder of the build. Here's running the download task from the command line:~/projects/duby ➔ rake ivy:download(in /Users/headius/projects/duby)mkdir -p ./ivyGetting: http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.0.0-beta1/ivy-2.0.0-beta1.jarTo: /Users/headius/projects/duby/ivy/ivy.jarNow we want a simple task that uses ivy:install to fetch resources and make them available for the build. Here's the example from Apache, using the cachepath task, written in Rake:task :go => "ivy:install" do ant.cachepath :organisation => "commons-lang", :module => "commons-lang", :revision => "2.1", :pathid => "lib.path.id", :inline => "true"endPretty clean and simple, and it fits nicely into the flow of the Rakefile. I can also switch this to using the "retrieve" task, which just pulls the jars down and puts them where I want them:task :go => "ivy:install" do ant.retrieve :organisation => 'commons-lang', :module => 'commons-lang', :revision => '2.1', :pattern => 'javalib/[conf]/[artifact].[ext]', :inline => trueendThis fetches the Apache Commons Lang package along with all dependencies into javalib, separated by what build configuration they are associated with (runtime, test, etc). Here it is in action:~/projects/duby ➔ rake go(in /Users/headius/projects/duby)mkdir -p ./ivyGetting: http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.0.0-beta1/ivy-2.0.0-beta1.jarTo: /Users/headius/projects/duby/ivy/ivy.jarNot modified - so not downloadedTrying to override old definition of task buildnumber:: Ivy 2.1.0 - 20090925235825 :: http://ant.apache.org/ivy/ :::: loading settings :: url = jar:file:/Users/headius/.ant/lib/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml:: resolving dependencies :: commons-lang#commons-lang-caller;working confs: [default, master, compile, provided, runtime, system, sources, javadoc, optional] found commons-lang#commons-lang;2.1 in public:: resolution report :: resolve 64ms :: artifacts dl 3ms --------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | default | 1 | 0 | 0 | 0 || 1 | 0 | | master | 1 | 0 | 0 | 0 || 1 | 0 | | compile | 1 | 0 | 0 | 0 || 0 | 0 | | provided | 1 | 0 | 0 | 0 || 0 | 0 | | runtime | 1 | 0 | 0 | 0 || 0 | 0 | | system | 1 | 0 | 0 | 0 || 0 | 0 | | sources | 1 | 0 | 0 | 0 || 1 | 0 | | javadoc | 1 | 0 | 0 | 0 || 1 | 0 | | optional | 1 | 0 | 0 | 0 || 0 | 0 | ---------------------------------------------------------------------:: retrieving :: commons-lang#commons-lang-caller confs: [default, master, compile, provided, runtime, system, sources, javadoc, optional] 4 artifacts copied, 0 already retrieved (1180kB/30ms)But if I have multiple artifacts, this could be pretty cumbersome. Since this is Ruby, I can just put this in a method and call it repeatedly:def ivy_retrieve(org, mod, rev) ant.retrieve :organisation => org, :module => mod, :revision => rev, :pattern => 'javalib/[conf]/[artifact].[ext]', :inline => trueendartifacts = %w[ commons-lang commons-lang 2.1 org.jruby jruby 1.4.0]task :go => "ivy:install" do artifacts.each_slice(3) do |*artifact| ivy_retrieve(*artifact) endendLook for JRuby 1.5 release candidates soon, and let us know what you think of the new Ant integration! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
JRuby 1.5 will be released soon, and one of the coolest new features is the integration of Ant support into Rake, the Ruby build tool. Tom Enebo wrote an article on the Rake/Ant integration for the Engine Yard blog, which has lots of examples of how ... [More] to start migrating to Rake without leaving Ant behind. I'm not going to cover all that here.I've been using the Rake/Ant stuff for a few weeks now, first for my "weakling" RubyGem which adds a queue-supporting WeakRef to JRuby, and now for cleaning up Duby's build process. Along the way, I've realized I really never want to write Ant scripts again; they're so much nicer in Rake, and I have all of Ruby and Ant available to me.One thing Ant still needs help with is dependency resolution. Many people make the leap to Maven, and let it handle all the nuts and bolts. But that only works if you really buy into the Maven way of life...a problem if you're like me and you live in a lot of hybrid worlds where the Maven way doesn't necessarily fit. So many folks are turning to Apache Ivy to get dependency management in their builds without using Maven.Today I thought I'd translate the simple "no-install" Ivy example build (warning, XML) to Rake, to see how easy it would be. The results are pretty slick.First we need to construct the equivalent to the "download-ivy" and "install-ivy" ant tasks. I chose to put that in a Rake namespace, like this:namespace :ivy do ivy_install_version = '2.0.0-beta1' ivy_jar_dir = './ivy' ivy_jar_file = "#{ivy_jar_dir}/ivy.jar" task :download do mkdir_p ivy_jar_dir ant.get :src => "http://repo1.maven.org/maven2/org/apache/ivy/ivy/#{ivy_install_version}/ivy-#{ivy_install_version}.jar", :dest => ivy_jar_file, :usetimestamp => true end task :install => :download do ant.path :id => 'ivy.lib.path' do fileset :dir => ivy_jar_dir, :includes => '*.jar' end ant.taskdef :resource => "org/apache/ivy/ant/antlib.xml", #:uri => "antlib:org.apache.ivy.ant", :classpathref => "ivy.lib.path" endendNotice that instead of using Ant properties, I've just used Ruby variables for the Ivy install version, dir, and file. I've also removed the "uri" element to ant.taskdef because I'm not sure if we have an equivalent for that in Rake yet (note to self: figure out if we have an equivalent for that).With these two tasks, we can now fetch ivy and install it for the remainder of the build. Here's running the download task from the command line:~/projects/duby ➔ rake ivy:download(in /Users/headius/projects/duby)mkdir -p ./ivyGetting: http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.0.0-beta1/ivy-2.0.0-beta1.jarTo: /Users/headius/projects/duby/ivy/ivy.jarNow we want a simple task that uses ivy:install to fetch resources and make them available for the build. Here's the example from Apache, using the cachepath task, written in Rake:task :go => "ivy:install" do ant.cachepath :organisation => "commons-lang", :module => "commons-lang", :revision => "2.1", :pathid => "lib.path.id", :inline => "true"endPretty clean and simple, and it fits nicely into the flow of the Rakefile. I can also switch this to using the "retrieve" task, which just pulls the jars down and puts them where I want them:task :go => "ivy:install" do ant.retrieve :organisation => 'commons-lang', :module => 'commons-lang', :revision => '2.1', :pattern => 'javalib/[conf]/[artifact].[ext]', :inline => trueendThis fetches the Apache Commons Lang package along with all dependencies into javalib, separated by what build configuration they are associated with (runtime, test, etc). Here it is in action:~/projects/duby ➔ rake go(in /Users/headius/projects/duby)mkdir -p ./ivyGetting: http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.0.0-beta1/ivy-2.0.0-beta1.jarTo: /Users/headius/projects/duby/ivy/ivy.jarNot modified - so not downloadedTrying to override old definition of task buildnumber:: Ivy 2.1.0 - 20090925235825 :: http://ant.apache.org/ivy/ :::: loading settings :: url = jar:file:/Users/headius/.ant/lib/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml:: resolving dependencies :: commons-lang#commons-lang-caller;working confs: [default, master, compile, provided, runtime, system, sources, javadoc, optional] found commons-lang#commons-lang;2.1 in public:: resolution report :: resolve 64ms :: artifacts dl 3ms --------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | default | 1 | 0 | 0 | 0 || 1 | 0 | | master | 1 | 0 | 0 | 0 || 1 | 0 | | compile | 1 | 0 | 0 | 0 || 0 | 0 | | provided | 1 | 0 | 0 | 0 || 0 | 0 | | runtime | 1 | 0 | 0 | 0 || 0 | 0 | | system | 1 | 0 | 0 | 0 || 0 | 0 | | sources | 1 | 0 | 0 | 0 || 1 | 0 | | javadoc | 1 | 0 | 0 | 0 || 1 | 0 | | optional | 1 | 0 | 0 | 0 || 0 | 0 | ---------------------------------------------------------------------:: retrieving :: commons-lang#commons-lang-caller confs: [default, master, compile, provided, runtime, system, sources, javadoc, optional] 4 artifacts copied, 0 already retrieved (1180kB/30ms)But if I have multiple artifacts, this could be pretty cumbersome. Since this is Ruby, I can just put this in a method and call it repeatedly:def ivy_retrieve(org, mod, rev) ant.retrieve :organisation => org, :module => mod, :revision => rev, :pattern => 'javalib/[conf]/[artifact].[ext]', :inline => trueendartifacts = %w[ commons-lang commons-lang 2.1 org.jruby jruby 1.4.0]task :go => "ivy:install" do artifacts.each_slice(3) do |*artifact| ivy_retrieve(*artifact) endendLook for JRuby 1.5 release candidates soon, and let us know what you think of the new Ant integration! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
JRuby 1.5 will be released soon, and one of the coolest new features is the integration of Ant support into Rake, the Ruby build tool. Tom Enebo wrote an article on the Rake/Ant integration for the Engine Yard blog, which has lots of examples of how ... [More] to start migrating to Rake without leaving Ant behind. I'm not going to cover all that here.I've been using the Rake/Ant stuff for a few weeks now, first for my "weakling" RubyGem which adds a queue-supporting WeakRef to JRuby, and now for cleaning up Duby's build process. Along the way, I've realized I really never want to write Ant scripts again; they're so much nicer in Rake, and I have all of Ruby and Ant available to me.One thing Ant still needs help with is dependency resolution. Many people make the leap to Maven, and let it handle all the nuts and bolts. But that only works if you really buy into the Maven way of life...a problem if you're like me and you live in a lot of hybrid worlds where the Maven way doesn't necessarily fit. So many folks are turning to Apache Ivy to get dependency management in their builds without using Maven.Today I thought I'd translate the simple "no-install" Ivy example build (warning, XML) to Rake, to see how easy it would be. The results are pretty slick.First we need to construct the equivalent to the "download-ivy" and "install-ivy" ant tasks. I chose to put that in a Rake namespace, like this:namespace :ivy do ivy_install_version = '2.0.0-beta1' ivy_jar_dir = './ivy' ivy_jar_file = "#{ivy_jar_dir}/ivy.jar" task :download do mkdir_p ivy_jar_dir ant.get :src => "http://repo1.maven.org/maven2/org/apache/ivy/ivy/#{ivy_install_version}/ivy-#{ivy_install_version}.jar", :dest => ivy_jar_file, :usetimestamp => true end task :install => :download do ant.path :id => 'ivy.lib.path' do fileset :dir => ivy_jar_dir, :includes => '*.jar' end ant.taskdef :resource => "org/apache/ivy/ant/antlib.xml", #:uri => "antlib:org.apache.ivy.ant", :classpathref => "ivy.lib.path" endendNotice that instead of using Ant properties, I've just used Ruby variables for the Ivy install version, dir, and file. I've also removed the "uri" element to ant.taskdef because I'm not sure if we have an equivalent for that in Rake yet (note to self: figure out if we have an equivalent for that).With these two tasks, we can now fetch ivy and install it for the remainder of the build. Here's running the download task from the command line:~/projects/duby ➔ rake ivy:download(in /Users/headius/projects/duby)mkdir -p ./ivyGetting: http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.0.0-beta1/ivy-2.0.0-beta1.jarTo: /Users/headius/projects/duby/ivy/ivy.jarNow we want a simple task that uses ivy:install to fetch resources and make them available for the build. Here's the example from Apache, using the cachepath task, written in Rake:task :go => "ivy:install" do ant.cachepath :organisation => "commons-lang", :module => "commons-lang", :revision => "2.1", :pathid => "lib.path.id", :inline => "true"endPretty clean and simple, and it fits nicely into the flow of the Rakefile. I can also switch this to using the "retrieve" task, which just pulls the jars down and puts them where I want them:task :go => "ivy:install" do ant.retrieve :organisation => 'commons-lang', :module => 'commons-lang', :revision => '2.1', :pattern => 'javalib/[conf]/[artifact].[ext]', :inline => trueendThis fetches the Apache Commons Lang package along with all dependencies into javalib, separated by what build configuration they are associated with (runtime, test, etc). Here it is in action:~/projects/duby ➔ rake go(in /Users/headius/projects/duby)mkdir -p ./ivyGetting: http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.0.0-beta1/ivy-2.0.0-beta1.jarTo: /Users/headius/projects/duby/ivy/ivy.jarNot modified - so not downloadedTrying to override old definition of task buildnumber:: Ivy 2.1.0 - 20090925235825 :: http://ant.apache.org/ivy/ :::: loading settings :: url = jar:file:/Users/headius/.ant/lib/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml:: resolving dependencies :: commons-lang#commons-lang-caller;working confs: [default, master, compile, provided, runtime, system, sources, javadoc, optional] found commons-lang#commons-lang;2.1 in public:: resolution report :: resolve 64ms :: artifacts dl 3ms --------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | default | 1 | 0 | 0 | 0 || 1 | 0 | | master | 1 | 0 | 0 | 0 || 1 | 0 | | compile | 1 | 0 | 0 | 0 || 0 | 0 | | provided | 1 | 0 | 0 | 0 || 0 | 0 | | runtime | 1 | 0 | 0 | 0 || 0 | 0 | | system | 1 | 0 | 0 | 0 || 0 | 0 | | sources | 1 | 0 | 0 | 0 || 1 | 0 | | javadoc | 1 | 0 | 0 | 0 || 1 | 0 | | optional | 1 | 0 | 0 | 0 || 0 | 0 | ---------------------------------------------------------------------:: retrieving :: commons-lang#commons-lang-caller confs: [default, master, compile, provided, runtime, system, sources, javadoc, optional] 4 artifacts copied, 0 already retrieved (1180kB/30ms)But if I have multiple artifacts, this could be pretty cumbersome. Since this is Ruby, I can just put this in a method and call it repeatedly:def ivy_retrieve(org, mod, rev) ant.retrieve :organisation => org, :module => mod, :revision => rev, :pattern => 'javalib/[conf]/[artifact].[ext]', :inline => trueendartifacts = %w[ commons-lang commons-lang 2.1 org.jruby jruby 1.4.0]task :go => "ivy:install" do artifacts.each_slice(3) do |*artifact| ivy_retrieve(*artifact) endendLook for JRuby 1.5 release candidates soon, and let us know what you think of the new Ant integration! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
This year, no major Ruby organization got accepted to Google's Summer of Code (even though a half dozen Python projects got accepted, but I won't rant here). What do we as Rubyists do? Take it sitting down? NO! We make our own Summer of Code!Thanks ... [More] to Engine Yard, Ruby Central, and the Rails team, Ruby Summer of Code has raised $100k in just three days, allowing us to run 20 student projects! Hooray!Ruby Summer of CodeNow of course we really would love to have some JRuby projects involved. There's so much exciting stuff going on with JRuby, and I believe it's the most promising platform for really growing the Ruby community. So we've set up a page for JRuby Ruby Summer of Code 2010 ideas. Here's a few to get you started:JRuby on Android work, including command-line tooling, performance work, and all the little bits and pieces needed to make Ruby a first-class Android language.Porting key C extensions to JRuby, so there's an alternative for people migrating.A super-fast lightweight server similar to the GlassFish gem.A full Hibernate and/or JPA backend for DataMapper or DataObjects, so that all databases Hibernate supports "just work" with JRuby.Work on JRuby's nascent suport for Ruby C extensions by building the API outHelp get JRuby's early optimizing compiler wired up, to take JRuby's perf to the next levelDuby-related projects, like IDE support, better tooling, codebase cleanup, features, documentation.And there's dozens of other projects out there just waiting for you! Add yourself as a student on the RubySOC page, add some ideas to the JRuby ideas page, and let's get hacking! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
This year, no major Ruby organization got accepted to Google's Summer of Code (even though a half dozen Python projects got accepted, but I won't rant here). What do we as Rubyists do? Take it sitting down? NO! We make our own Summer of Code!Thanks ... [More] to Engine Yard, Ruby Central, and the Rails team, Ruby Summer of Code has raised $100k in just three days, allowing us to run 20 student projects! Hooray!Ruby Summer of CodeNow of course we really would love to have some JRuby projects involved. There's so much exciting stuff going on with JRuby, and I believe it's the most promising platform for really growing the Ruby community. So we've set up a page for JRuby Ruby Summer of Code 2010 ideas. Here's a few to get you started:JRuby on Android work, including command-line tooling, performance work, and all the little bits and pieces needed to make Ruby a first-class Android language.Porting key C extensions to JRuby, so there's an alternative for people migrating.A super-fast lightweight server similar to the GlassFish gem.A full Hibernate and/or JPA backend for DataMapper or DataObjects, so that all databases Hibernate supports "just work" with JRuby.Work on JRuby's nascent suport for Ruby C extensions by building the API outHelp get JRuby's early optimizing compiler wired up, to take JRuby's perf to the next levelDuby-related projects, like IDE support, better tooling, codebase cleanup, features, documentation.And there's dozens of other projects out there just waiting for you! Add yourself as a student on the RubySOC page, add some ideas to the JRuby ideas page, and let's get hacking! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
This year, no major Ruby organization got accepted to Google's Summer of Code (even though a half dozen Python projects got accepted, but I won't rant here). What do we as Rubyists do? Take it sitting down? NO! We make our own Summer of Code!Thanks ... [More] to Engine Yard, Ruby Central, and the Rails team, Ruby Summer of Code has raised $100k in just three days, allowing us to run 20 student projects! Hooray!Ruby Summer of CodeNow of course we really would love to have some JRuby projects involved. There's so much exciting stuff going on with JRuby, and I believe it's the most promising platform for really growing the Ruby community. So we've set up a page for JRuby Ruby Summer of Code 2010 ideas. Here's a few to get you started: JRuby on Android work, including command-line tooling, performance work, and all the little bits and pieces needed to make Ruby a first-class Android language. Porting key C extensions to JRuby, so there's an alternative for people migrating. A super-fast lightweight server similar to the GlassFish gem. A full Hibernate and/or JPA backend for DataMapper or DataObjects, so that all databases Hibernate supports "just work" with JRuby. Work on JRuby's nascent suport for Ruby C extensions by building the API out Help get JRuby's early optimizing compiler wired up, to take JRuby's perf to the next level Duby-related projects, like IDE support, better tooling, codebase cleanup, features, documentation. And there's dozens of other projects out there just waiting for you! Add yourself as a student on the RubySOC page, add some ideas to the JRuby ideas page, and let's get hacking! [Less]
Posted over 16 years ago by [email protected] (Charles Oliver Nutter)
JRuby has become notorious among Ruby implementations for having a slow startup time. Some of this is the JVM's fault, since it doesn't save JIT products and often just takes a long time to boot and get going. Some of this is JRuby's fault, though we ... [More] work very hard to eliminate startup bottlenecks once they're reported and diagnosed. But a large number of startup time problems stem from simple configuration issues. Here's a few tips to help you improve JRuby's startup time.(Note: JRuby actually does pretty well on base startup time compared to other JVM languages; but MRI, while generally not the fastest Ruby impl, starts up incredibly fast.)Make sure you're running the client JVMThis is by far the easiest way to improve startup. On HotSpot, the JVM behind OpenJDK and Sun's JDK, there are two different JIT-compiling backends: "client" and "server". The "client" backend does only superficial optimizations to JVM code as it compiles, but compiles things earlier and more quickly. The "server" backend performs larger-scale, more-global optimizations as it compiles, but takes a lot longer to get there and uses more resources when it compiles.Up until recently, most JVM installs preferred the "client" backend, which meant JVM startup was about as fast as it could get. Unfortunately, many newer JVM releases on many operating systems are either defaulting to "server" or defaulting to a 64-bit JVM (which only has "server"). This means that without you or JRuby doing anything wrong, startup time takes a major hit.Here's an example session showing a typical jruby -v line for a "server" JVM and the speed of doing some RubyGems requires (which is where most time is spent booting a RubyGems-heavy application):~/projects/jruby ➔ jruby -vjruby 1.5.0.dev (ruby 1.8.7 patchlevel 174) (2010-03-01 6857a4e) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_17) [x86_64-java]~/projects/jruby ➔ time jruby -e "require 'rubygems'; require 'active_support'"real 0m5.174suser 0m7.643ssys 0m0.422s~/projects/jruby ➔ time jruby -e "require 'rubygems'; require 'active_support'"real 0m5.068suser 0m7.662ssys 0m0.449sOuch, over 5 seconds just to boot RubyGems and load ActiveSupport. You can see in this case that the JVM is preferring the "64-Bit Server VM", which will give you great runtime performance but pretty dismal startup time. If you see this sort of -v output, you can usually force the JVM to run in 32-bit "client" mode by specifying "-d32" as a JVM option. Here's an example using an environment variable:~/projects/jruby ➔ export JAVA_OPTS="-d32"~/projects/jruby ➔ time jruby -e "require 'rubygems'; require 'active_support'"real 0m2.320suser 0m2.583ssys 0m0.207s~/projects/jruby ➔ time jruby -e "require 'rubygems'; require 'active_support'"real 0m2.275suser 0m2.580ssys 0m0.207sOn my system, a MacBook Pro running OS X 10.6, switching to the "client" VM improves this scenario by well over 50%. You may also want to try the "-client" option alone or in combination with -d32, since some 32-bit systems will still default to "server". Play around with it and see what works for you, and then let us know your platform, -v string, and how much improvement you see.Regenerate the JVM's shared archiveStarting with Java 5, the HotSpot JVM has included a feature known as Class Data Sharing (CDS). Originally created by Apple for their OS X version of HotSpot, this feature loads all the common JDK classes as a single archive into a shared memory location. Subsequent JVM startups then simply reuse this read-only shared memory rather than reloading the same data again. It's a large reason why startup times on Windows and OS X have been so much better in recent years, and users of those systems may be able to ignore this tip.On Linux, however, the shared archive is often *never* generated, since installers mostly just unpack the JVM into its final location and never run it. In order to force your system to generate the shared archive, run some equivalent of this command line:headius@headius-desktop:~/jruby$ sudo java -Xshare:dumpLoading classes to share ... done.Rewriting and unlinking classes ... done.Calculating hash values for String objects .. done.Calculating fingerprints ... done.Removing unshareable information ... done.Moving pre-ordered read-only objects to shared space at 0x94030000 ... done.Moving read-only objects to shared space at 0x9444bef8 ... done.Moving common symbols to shared space at 0x9444d870 ... done.Moving remaining symbols to shared space at 0x945154e0 ... done.Moving string char arrays to shared space at 0x94516118 ... done.Moving additional symbols to shared space at 0x945ac5b0 ... done.Read-only space ends at 0x94612560, 6169952 bytes.Moving pre-ordered read-write objects to shared space at 0x94830000 ... done.Moving read-write objects to shared space at 0x94ea64a0 ... done.Moving String objects to shared space at 0x94ee3708 ... done.Read-write space ends at 0x94f27448, 7304264 bytes.Updating references to shared objects ... done. For many users, this can make a tremendous difference in startup time, since all that extra class data remains available in memory. You may need to specify the -d32 or -client options along with the -Xshare option. Play with those and the other -Xshare modes to see if it helps your situation.Delay or disable JRuby's JITAn interesting side effect of JRuby's JIT is that it sometimes actually slows execution for really short runs. The compiler isn't free, obviously, nor is the cost of loading, verifying, and linking the resulting JVM bytecode. If you have a very short command that touches a lot of code, you might want to try disabling or delaying the JIT.Disabling is easy: pass the -X-C flag or set the jruby.compile.mode property to "OFF":~/projects/jruby ➔ time jruby -S gem install rakeSuccessfully installed rake-0.8.71 gem installedInstalling ri documentation for rake-0.8.7...Installing RDoc documentation for rake-0.8.7...real 0m13.188suser 0m12.342ssys 0m0.685s~/projects/jruby ➔ time jruby -X-C -S gem install rakeSuccessfully installed rake-0.8.71 gem installedInstalling ri documentation for rake-0.8.7...Installing RDoc documentation for rake-0.8.7...real 0m12.590suser 0m12.342ssys 0m0.583sThis doesn't generally give you a huge boost, but it can be enough to keep you from going mad.Avoid spawning "sub-rubies"It's a fairly common idiom for Rubyists to spawn a Ruby subprocess using Kernel#system, Kernel#exec, or backquotes. For example, you may want to prepare a clean environment for a test run. That sort of scenario is perfectly understandable, but spawning many sub-rubies can take a tremendous toll on overall runtime.When JRuby sees a #system, #exec, or backquote starting with "ruby", we will attempt to run it in the same JVM using a new JRuby instance. Because we have always supported "multi-VM" execution (where multiple isolated Ruby environments share a single process), this can make spawning sub-Rubies considerably faster. This is, in fact, how JRuby's Nailgun support (more on that later) keeps a single JVM "clean" for multiple JRuby command executions. But even though this can improve performance, there's still a cost for starting up those JRuby instances, since they need to have fresh, clean core classes and a clean runtime.The worst-case scenario is when we detect that we can't spin up a JRuby instance in the same process, such as if you have shell redirection characters in the command line (e.g. system 'ruby -e blah > /dev/null'). In those cases, we have no choice but to launch an entirely new JRuby process, complete with a new JVM, and you'll be paying the full zero-to-running cost.If you're able, try to limit how often you spawn "sub-rubies" or use tools like Nailgun or spec-server to reuse a given process for multiple hits.Do less at startupThis is a difficult tip to follow, since often it's not your code doing so much at startup (and usually it's RubyGems itself). One of the sad truths of JRuby is that because we're based on the JVM, and the JVM takes a while to warm up, code executed early in a process runs a lot slower than code executed later. Add to this the fact that JRuby doesn't JIT Ruby code into JVM bytecode until it's been executed a few times, and you can see why cold performance is not one of JRuby's strong areas.It may seem like delaying the inevitable, but doing less at startup can have surprisingly good results for your application. If you are able to eliminate most of the heavy processing until an application window starts up or a server starts listening, you may avoid (or spread out) the cold performance hit. Smart use of on-disk caches and better boot-time algorithms can help a lot, like saving a cache of mostly-read-only data rather than reloading and reprocessing it on every boot.Try using NailgunIn JRuby 1.3, we officially shipped support for Nailgun. Nailgun is a small library and client-side tool that reuses a single JVM for multiple invocations. With Nailgun, small JRuby command-line invocations can be orders of magnitude faster. Have a look at my article on Nailgun in JRuby 1.3.0 for details.Nailgun seems like a magic bullet, but unfortunately it does little to help certain common cases like booting RubyGems or starting up Rails (such as when running tests). It also can't help cases where you are causing lots of sub-rubies to be launched. Your best bet is to give it a try and let us know if it helps.Play around with JVM flagsThere's scads of JVM flags that can improve (or degrade) startup time. For a good list of flags you can play with, see my article on my favorite JVM flags, paying special attention to the heap-sizing and GC flags. If you find combinations that really help your application start up faster, let us know!Help us find bottlenecksThe biggest advances in startup-time performance have come from users like you investigating the load process to see where all that time is going. If you do a little poking around and find that particular libraries take unreasonably long to start (or just do too much at startup) or if you find that startup time seems to be limited by something other than CPU (like if your hard drive starts thrashing madly or your memory bus is being saturated) there may be improvements possible in JRuby or in the libraries and code you're loading. Dig a little...you may be surprised what you find.Here's a few JRuby flags that might help you investigate:--sample turns on the JVM's sampling profiler. It's not super accurate, but if there's some egregious bottleneck it should rise to the top.-J-Xrunhprof:cpu=times turns on the JVM's instrumented profiler, saving profile results to java.hprof.txt. This slows down execution tremendously, but can give you more accurate low-level timings for JRuby and JDK code.-J-Djruby.debug.loadService.timing=true turns on timing of all requires, showing fairly accurately where boot-time load costs are heaviest.On Windows, where you may not have a "time" command, pass -b to JRuby (as in 'jruby -b ...') to print out a timing of your command's runtime execution (excluding JVM boot time).Let us help you!Sometimes, there's an obvious misconfiguration or bug in JRuby that causes an application to start up unreasonably slowly. If startup time seems drastically different than what you've seen here, there's a good chance something's wrong with your setup. Post your situation to the JRuby mailing list or find us on IRC, and we (along with other JRuby users) will do our best to help you. [Less]