"Cannot load Java class" in JRuby - jruby

I want to integrate a very simple Java file into my JRuby app. Unfortunately, it doesn't work.
Simple.java:
package com.mypackage;
public class Simple {
public void foo() {
System.out.println("foo called");
}
}
I compile it with "javac Simple.java"
Then I create a jar file with "jar cf mylib.jar Simple.class"
test.rb:
require 'java'
require "mylib.jar"
java_import 'com.mypackage.Simple'
When I run it with "ruby test.rb" I get the following error:
NameError: cannot load Java class com.mypackage.Simple
for_name at org/jruby/javasupport/JavaClass.java:1286
get_proxy_class at org/jruby/javasupport/JavaUtilities.java:34
I have no idea what I'm doing wrong.
My JRuby version is: jruby 1.7.16.1 (1.9.3p392)

The answer is simple. I have forgotten to put the Simple class into the folder structure com/mypackage/Simple. Java was therefore not able to find the class.

Related

Call abstract java class from jruby with a generic

Currently facing an issue while writing a similar java class in Jruby.
Example:
In Java:
public class Client extends ClientConnection<ChannelType> {
//do some stuff
}
In Jruby:
class Client < Java::'package_name'::ClientConnection
//do some stuff
end
Don't know how to pass ChannelType class in Jruby code while rewriting the Client class
The short version is, you can't unfortunately.
The JRuby wiki explains it as such here (https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#beware-of-java-generics):
If a Java class is defined with Java generics, the types are erased during compilation for backwards compatibility. As a result, JRuby will have problems with automatic type conversion. For example, if you have a Map, it will be seen as a simple Map, and JRuby will not be able to determine the correct types using reflection.

Problems with compiling multiple AS3 packages w/ant and mxmlc

I'm trying to extend the BigBlueButton client with some proprietary classes. Specifically the phone module, where I added a file with my own code. When I write my own package name (org.mydomain.module.test ...) within the file, the compiler fails because it can't find my class from the mxml file. But when I use the original package name (org.bigbluebutton.module.phone ...) it compiles fine. Obviously when I use a different package name, the file is not included in the compilation. How can I change this?
This fails:package org.mydomain.module.test
{
public class MyTestClass
{
// code here
}
}
But this works:package org.bigbluebutton.modules.phone.test
{
public class MyTestClass
{
// code here
}
}
FYI: BigBlueButton uses ant to compile the client.
You didn't say where you put the files on disk, the package name should match the file's path in your project. Is that the case in both examples?
So when the package name is: org.mydomain.module.test
The class file should be saved in the path:
my_project_path/src/org/mydomain/module/test

Jruby rb to java generated class inheritance support or workarounds

I am experimenting around with JRuby - generating java from ruby files. I have an abstract class in ruby that implement a Java interface, and child classes extending this. also in ruby.
I'm running into the problem as described on http://jira.codehaus.org/browse/JRUBY-6342 where all the generated java files only extend RubyObject.
I am wondering if anyone else has encountered this and have a workaround? Right now I have used a java_implement interface in each child class as they do not extend the abstract class.
I have included the snippet from JRUBY-6342 describing the problem:
The Java code generated by jrubyc --java does not appear to support Ruby class inheritance. Given the following simple example:
class A
def my_class; self.class.name end
end
class B < A
end
The generated class in B.java inherits from RubyObject rather than A, rendering the B class completely broken in Java.
On a somewhat related note, module inclusion doesn't seem to work either. A class with include M doesn't get M's methods in the generated Java code.
Am I missing something in my understanding of Ruby or JRuby?
This is still an issue indeed as the jruby compiler still produces RubyObject for the classes.
The only workaround that I know to this is to use the JRuby ScriptEngine from Java to eval your JRuby code. For example, here is some JRuby code:
require 'java'
java_import 'javax.swing.JFrame'
java_import 'javax.swing.JButton'
class MyFrame < JFrame
def initialize
super('Test')
content_pane.add(JButton.new("Hello"))
pack()
end
end
This code can then be called from a Java class like this:
import javax.swing.JFrame;
import javax.script.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jruby");
Reader reader = new FileReader("myframe.rb");
engine.eval(reader);
// Instantiate the JRuby class, and cast the result of eval.
JFrame frame = (JFrame) engine.eval("MyFrame.new");
frame.setVisible(true);
}
}
Here the object returned by eval can be casted into JFrame, just as you would expect. See also this question for that problem.

How to jmock Final class

I was trying to mock final class(AnyFinalClass.java) in junit using JDave in eclipse.
public void setUp() throws Exception {
Mockery mockery = new Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
AnyFinalClass any = mockery.mock(AnyFinalClass.class);
}
I am trying to use jdave-unfinalizer-1.1.jar as javaagent but didnt had any success. I tried multiple things but getting following exception
java.lang.IllegalArgumentException: Cannot subclass final class class AnyFinalClass
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
Can someone who has already tried jdave unfinalizer give me exact step how to make it work on eclipse.
I set following in eclipse.ini file but got the problem
-Xbootclasspath/a:lC:\WS\JunitTesting\jars\asm-3.0.jar
-javaagent:C:\WS\JunitTesting\jars\jdave-unfinalizer-1.1.jar
While running executing the junit, I gave vm argument as
javaagent:C:\WS\JunitTesting\jars\jdave-unfinalizer-1.1.jar
I am not sure what will be the code. jdave is not having the code and its site is pointing to some other site which is not working. Please correct my code or provide your same working code.
Any help is highly appreciated.
from Enhancer.java line 446:
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc);
I have not worked with JDave but with another mocking frameworks and the only one that allows to mock a final class was powermock
Look also here
In order to get unfinalizer running you have to put -javaagent:path_to_unfinalizer/jdave-unfinalizer-1.1.jar in the VM arguments of the run configuration of the test.
I also had to include several dependencies of jdave-unfinalizer in the classpath of the project from which the tests ar being launched. These are, taken from the maven definitions of jdave:
jdave-core 1.1
cglib-nodep 2.1_3
objenesis 1.0
asm 3.0
asm-commons 3.0
asm-tree 3.0

Using Custom Java Class file in Jruby

I am trying to execute some custom Java code through the latest version of Jruby (1.5.1), Ruby 1.8.7, with Java 1.6.0_06. I have tried both the class file and putting it in a jar method. When I try
require 'java'
require 'path_to_class/myClass
or
require 'java'
require 'path_to_jar/a_jar.jar
Trying both methods, I cannot access the myClass nor any other files in the jar file. Other variations on the net for importing java classes lead to the following error:
`NameError: cannot load Java class com.package.myClass from C:/jruby-1.5.1/lib/ruby/site_ruby/shared/builtin/javasupport/java.rb:51:in method_missing`
I have also checked the solutions on StackOverFlow and I still get the same outcome. I am wondering if this might be a problem at a deeper level.
Instead of 'require', you want 'java_import'.
require 'java'
java_import com.package.MyClass
See JRuby: import vs include vs java_import vs include_class for some more discussion e.g. why you should use 'java_import' instead of just 'import'
If you have a Java class com.mypackage.MyClass in the same folder, or in a folder present on the classpath, you can call it from your JRuby script like this:
require 'java'
import com.pack.MyClass
myClass = MyClass.new
If the class is in a jar, you have to require the jar:
require 'java'
require '/path/to/myjar.jar'
import com.pack.MyClass
myClass = MyClass.new
If myjar.jar is on the classpath, you can just use require 'myjar.jar'.
Did you try include Java?
See this for more details: http://blogs.oracle.com/coolstuff/entry/using_java_classes_in_jruby
So Here is what worked for me, I had all required stuff that people suggested but what I really needed was
$CLASSPATH << (Rails.root.to_s + "/path/to/dotClassFolder")
before the java_import statement
so in the file system, if your class was was in the folder
Rails.root/path/to/dotClassFolder/folder/anotherFolder/MyClass.class
Include $CLASSPATH << (Rails.root.to_s + "/path/to/dotClassFolder")
then java_import "folder.anotherFolder.MyClass"
See
From .class files section at https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby