I am scripting Java using JRuby. By using JRebel, I can the automatically reload changed Java classes into the JRuby JVM without restarting. When I add a new Java method JRebel automatically reloads the class. My problem is that I cannot call this new method directly. Can I ask JRuby to refresh its method cache for the newly reloaded Java class? My only workaround is to call the new method reflectively using java_send.
Example:
step 1. Start irb session and java_import a Java class (say Person).
step 2. Add a getName method to Person and compile.
step 3. Create an instance of Person (p = Person.new). JRebel will show that it reloaded the java class.
step 4. Calling p.get_name results in a NoMethodError but p.java_send('getName') invokes the newly implemented getName method
I found a way to run JRuby with JRebel!
The trick is to start JRuby with Nailgun server which is using the JRebel like this:
jruby --ng-server -J-javaagent:/Applications/ZeroTurnaround/JRebel/jrebel.jar -J-noverify
Now rails application can be started with Nailgun:
jruby --ng -S rails server
If rails uses Java classes from somewhere and it can find proper rebel.xml, the JRebel will pickup the changes and you don't need to restart the rails anymore.
$CLASSPATH << "#{RAILS_ROOT}/java/target/classes"
JRuby/JRebel still needs more work as the JRuby is not picking up the changes to the class declarations, only the contents of the known methods.
Did you manage to pass the -javaagent option so that it gets recognized by JIRB and start jrebel agent?
jruby -J-noverify -J-javaagent:/path/to/jrebel.jar -S jirb
I've tried this, but don't see it working, also with java_send
精彩评论