Scripting NetBeans in Ruby

Few times we were asked whether is is possible to write NetBeans Ruby IDE extensions in Ruby. We usually replied not yet. But having:

  • NetBeans running on the JVM
  • JRuby on the same VM
  • JSR 223 which is part of JDK 6

there are no reasons why it should not be possible now.

So I've started to peek around what would be needed to provide convenient extension with which the Rubyists would be able to start to tweak NetBeans IDE in Ruby language only. I did not start exactly with such support, but instead started with kind of NetBeans Ruby IDE scripting support. I've recalled Jesse's idea for IDE scripted by JavaScript and applied similar to Ruby.

Working with NetBeans Ruby's dev builds and very often starting with clear userdir and still reopening my projects, I now have the following script instead which I simply run from CLI after fresh NetBeans starts up (just work from IRB as well):

  1 require 'nb_ext'
  2 netbeans = NBExt.find_first
  3 netbeans.attach
  4 netbeans.open_projects(
  5   '/space/java/netbeans-hg/main/ruby.debugger',
  6   '/space/java/netbeans-hg/main/ruby.platform',
  7   '/space/java/netbeans-hg/main/ruby.project'
  8 )

How does it work?

Below are some details of implementation with inlined snippets of code for convenience. Full code might be downloaded here, Java agent here.

(2) The script finds running NetBeans instance. The find_first methods goes through the currently running JVM instances and greps for the NetBeans and returns the first one (or nil). Thus if you are running more NetBeans instances use find_by_userdir or find_all instead.

  1 vm_desc = VirtualMachine.list.detect do |desc|
  2   desc.display_name =~ /org.netbeans.Main/i
  3 end

(3) attach to it via Attach API

  1 VirtualMachine.attach(@vm_desc)t

(4) and opens given project(s) in the running NetBeans IDE. open_projects method just compose projects to be opened with the code utilizing NetBeans APIs (open_projects_code.rb) and sends it to the agent, running inside NetBeans process VM, for evaluation.

   1 def open_projects(\*projects)
   2   code = "projects = ['#{projects.join("','")}']\\n"
   3   code_file = File.join('code', 'open_projects_code.rb')
   4   code << File.read(code_file)
   5   eval_code(code)
   6 end
   7 
   8 def eval_code(code)
   9   output = Tempfile.new('output')
  10   @vm.load_agent(@agent_jar, "#{output.path}#{File::PATH_SEPARATOR}#{code}")
  11   File.read(output.path)
  12 end

Template for opening projects is simple:

   1 include Java
   2 
   3 import 'java.net.URI'
   4 import 'org.netbeans.api.project.FileOwnerQuery'
   5 import 'org.netbeans.api.project.ui.OpenProjects'
   6 
   7 raise("projects must be defined") unless defined?(projects)
   8 
   9 to_open = projects.map do |prj|
  10   uri = URI.new("file://#{prj}")
  11   FileOwnerQuery.get_owner(uri)
  12 end.compact
  13 
  14 to_open_p = to_open.to_java('org.netbeans.api.project.Project')
  15 OpenProjects.getDefault().open(to_open_p, false)

Note that projects variable is defined in the open_projects method code composition. Likely templating mechanism would fit here.

Everything written in the Ruby language, just agent class is written in Java (with future JRuby compiler even this piece could be written in Ruby).

Just a playground so far…

This is really just an example how it might be done. Developing such extensions, or writing such scripts, is still little awkward and not that easy to test and one needs to know NetBeans APIs, but that's likely OK when wanting to write NetBeans extensions/scripts.
In the future we could bridge some basic NetBeans APIs to Ruby, like the artificial open_projects method above, to make it easy to write such scripts which adds e.g. new menu items. Also it should not be hard to write some support into NetBeans where you would manage your scripts and which will be automatically loaded when NetBeans starts up. Ideally there would be also some support for testing such script -> write in IDE, run/test it in IDE. Not that simple, but something like this.

It depends whether there is really such a request from NetBeans Ruby users and whether the effort spends on the support does worth it, whether the NetBeans users would like to script or extends NetBeans in Ruby and what would be such use-cases.

If you have any ideas how such support should look like or how does it look in other IDEs, Editors supporting Ruby extensions, let me know.

Can I try it?

Yes, you can. But it might not be that easy at the moment since we are facing issue with bundled tweaked JRuby. So firstly you might try to download and install this NetBeans module (4384kB!, contains jruby.jar) which should enable JRuby scripting in Netbeans. I've spent some time with this but still does not work. On the other hand my colleague Erno, does not have problems I'm encountering. So your mileage may vary.
If it throws strange JRuby internal exceptions, use second brute-force method, and just copy-paste jruby.jar from your JRuby distribution (lib/jruby.jar) and jruby-engine jar to your $JAVA_HOME/jre/lib/ext directory. Then start the NetBeans IDE and above should work. You will get some exceptions from our NetBeans Ruby lexer/parser if you used brute-force method, but for playing should be enough until we solve the issue appropriately.

Comments:

Yeah!!! :) This kind of functionality would be really sweet to have and to play with.

All kinds of exploratory activities would be much easier once the nice scripting support is there to use.

Posted by Vladimir Sizikov on May 07, 2008 at 06:59 PM PDT #

@Vladimir> I'm still fighting with JRuby engine utilized from NetBeans. Getting strange JRuby's internal exceptions. Will take a look into engine's source what going on and possibly ping you and other from team on #jruby channel.

Otherwise this is not actually Ruby related, it might be done in every JVM language. But I suppose we would have to bridge NetBeans API to each language which we want to support from NetBeans. At least a little bit of abstraction to make entry point easy. Having JRuby mature enough, it is ideal candidate for doing such explorations.

Will think about possibilities more in the future. I'm curious whether there was such attempts in the past, whether somebody tried to write some kind of support for some JVM language.

Posted by Martin Krauskopf on May 07, 2008 at 07:19 PM PDT #

This is awesome. I look forward to playing with it some day.

Posted by Brandon on May 07, 2008 at 11:31 PM PDT #

Good to know Brandon. Let me know if you encounter problems, since as I said, I've encountered bunch of them. I'll now fully work on the debuggers, but then I'm planning to continue on this. Will post update here.

Posted by Martin Krauskopf on May 07, 2008 at 11:57 PM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Martin Krauskopf

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today