Я пытаюсь использовать ActiveRecord из Java через JRuby, но сталкиваюсь с проблемой "ClassCastExcecption".
Пример приложения реализован следующим образом:
Пример / 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
Но, как ни странно, если я прокомментирую строку (A) из Main.java, я получу 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' до эквивалентного кода с помощью Class #. Распределите следующим образом:
u = User.allocate
u.send :initialize, {:name => name}
u
Почему Class # new должен вызываться заранее, чтобы избежать ClassCastException? Я что-то упустил?
Я использую JRuby 1.5.6. Драгоценные камни:
- activerecord 3.0.3
- activerecord-jdbc-адаптер 1.1.0
- activerecord-jdbcsqlite3-adapter 1.1.0