2011-01-10 59 views
1

我想通過JRuby從Java使用ActiveRecord,但是面臨「ClassCastExcecption」問題。從Java使用ActiveRecord時出現奇怪的ClassCastException

該示例應用程序實現如下:

示例/ User.java

package example; 

public interface User { 
    String getName(); 
} 

示例/ UserManager.java

package example; 

import java.util.List; 

public interface UserManager { 
    List<User> all_users(); 
    User new_user(String name); 
} 

user_manager.rb(類路徑中的某處)

require 'rubygems' 
require 'arjdbc' 

class User < ActiveRecord::Base 
    include Java::example.User 
end 

class UserManager 
    include Java::example.UserManager 

    def initialize 
    ActiveRecord::Base.establish_connection(
     :adapter => "jdbcsqlite3", 
     :database => "test.db" 
    ) 
    end 

    def new_user(name) 
    User.new(:name => name) 
    end 

    def all_users 
    User.all 
    end 
end 

UserManager.new 

示例/ Main.java

package example; 

import org.jruby.embed.PathType; 
import org.jruby.embed.ScriptingContainer; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     ScriptingContainer container = new ScriptingContainer(); 
     container.setHomeDirectory("D:/bin/jruby-1.5.6"); // JRuby path 

     Object userManagerObj = container.runScriptlet(
       PathType.CLASSPATH, "user_manager.rb"); 
     UserManager userManager = container.getInstance(
       userManagerObj, UserManager.class); 

     userManager.new_user("Jane Doe"); // (A) 

     System.out.println("Users:"); 
     for (User user : userManager.all_users()) { 
      System.out.println(user.getName()); 
     } 
    } 
} 

'用戶' 表被事先設置如下:

ActiveRecord::Schema.define do 
    create_table :users, :force => true do |t| 
    t.column :name, :string 
    end 
end 

User.create(:name => 'John Doe') 

當運行上述的主類,一切都很好。

Users: 
John Doe 

但奇怪的是,如果我將Main.java中的行(A)註釋掉,我得到一個ClassCastException異常。

Users: 
Exception in thread "main" java.lang.ClassCastException: org.jruby.RubyObject cannot be cast to example.User 
    at example.Main.main(Main.java:17) 

還可以得到一個ClassCastException - 如果我更新「new_user」的方法來使用類#等效代碼分配如下:

u = User.allocate 
u.send :initialize, {:name => name} 
u 

爲什麼類#新必須提前打電話來避免拋出ClassCastException?我錯過了什麼嗎?

我正在使用JRuby 1.5.6。寶石:

  • 的ActiveRecord 3.0.3
  • 的ActiveRecord-JDBC適配器1.1.0
  • 的ActiveRecord-jdbcsqlite3適配器1.1.0

回答

相關問題