Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Xcode: Accessing Java from Objective C System
Getting and using Java objects in Objective-C Cocoa projects is easy ... once you figure it out. Unfortunately, Apple's documentation on this topic is not only scarce, it is also inaccurate. The goal of my hint is to provide you with the ability to develop a project including your own Objective-C code, Java library classes, and your own Java classes.

To facilitate your ability to see how this works in practice, my explanation I will use a Foundation tool. Note: I have verified that the same steps work for any Objective-C project type

Read the rest of the hint for the step-by-step explanation...

  1. Create a new Foundation project called "HelloBridge"
  2. Create a new Pure Java Package target called "JavaClasses"
  3. Create a new Java class called "HelloBridge.java" an add it to target "JavaClasses":
    
    public class HelloBridge {
       private String string = "Hello";
    
       public void setString(String string) {
          this.string = string;
       }
    
       public String getString() {
          return this.string;
       }
    
       public void printString() {
          System.out.println(this.string);
       }
    }
    
  4. Add "HelloBridge.java" to the "Sources" build phase in target "JavaClasses"
  5. Create a new empty file called "JavaInterfaces.h" and add it to target "HelloBridge":
    
    // Provide Objective-C interfaces for the Java classes
    // Not only good practice, it provides Code Sense
    @interface java_util_Vector : NSObject
    {}
    - (void)add:(id)anObject;
    - (id)get:(int)index;
    @end
    
    @interface HelloBridge : NSObject
    {}
    - (void)setString:(NSString *)string;
    - (NSString *)getString;
    - (void)printString;
    @end
    
  6. Modify "main.m":
    
    #import <Foundation/Foundation.h>
    #import "JavaInterfaces.h"
    
    int main (int argc, const char * argv[]) {
       NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
       
       // Load the Java VM
       id vm = NSJavaSetupVirtualMachine();
       
       // Start the Java class loader
       NSJavaClassesFromPath(nil, nil, YES, &vm);
       
       // Load a new instance of the java.util.Vector Java class into an Objective-C pointer
       java_util_Vector * vector = NSJavaObjectNamedInPath(@"java.util.Vector", nil);
       [vector add:@"one item!"];
       NSLog(@"item 1=%@",[vector get:0]);
       [vector release];
       
       // Load a new instance of our custom HelloBridge Java class into an Objective-C pointer
       HelloBridge * hello = NSJavaObjectNamedInPath(@"HelloBridge", nil);
       NSLog(@"item 1=%@",[hello getString]);
       [hello setString:@"Test"];
       NSLog(@"item 1=%@",[hello getString]);
       [hello printString];
       [hello release];
       
       [pool release];
       return 0;
    }
    
  7. Select "JavaClasses" from the targets drop box and Build it
  8. Select "HelloBridge" from the targets drop box and Build/Run it
  9. Gloat to all of your friends about how awesome OS X is for development
[robg adds: I have not tested this one, as it's well beyond my area of expertise.]
    •    
  • Currently 3.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (2 votes cast)
 
[26,052 views]  

Xcode: Accessing Java from Objective C | 7 comments | Create New Account
Click here to return to the 'Xcode: Accessing Java from Objective C' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Xcode: Accessing Java from Objective C
Authored by: Lizard_King on Mar 26, '04 11:50:19AM

Hard to gloat as a Java developer - still feel like a second class citizen.

Does XCode support full CodeSense for Java yet?



[ Reply to This | # ]
Xcode: Accessing Java from Objective C
Authored by: Morgoth on Mar 26, '04 12:32:43PM

Good point. Xcode has incomplete support for Java. It's "smart" indenting causes great headaches because the idea of implementing the code of a class in place (as is the requirement in Java) is foreign to it.

What I recommend the bridge for is accessing useful Java frameworks from a Cocoa Objective-C applications. I am using it to develop an application which uses a bunch of Apache XML frameworks to process DocBook files to generate HTML and PDF.

Java developers are in no way second-class citizens on OS X. Neither Windows, nor more Linux distros have built-in support for Java development. At least Apple tried.

If you intend to develop a library or app in Java I recommend using Eclipse. Once you have a library or backend implemeted in Java, developed in a full-featured Java IDE, then it is straight-forward to bring the code into Xcode for integration with a Mac OS X Application you are developing.



[ Reply to This | # ]
Other Hints
Authored by: jamus on Mar 26, '04 01:56:21PM

I found this page to be a great, quick reference: http://cocoadevcentral.com/articles/000024.php

To call a function with more than one parameter, call it like: [class funcName:arg1 :arg2 :arg3 :arg4];

If you're not sure what Java object the Objective-C object got wrapped around, I cast that parameter as an object, and use System.out.println(class.getClass().getName()); to print out the class name.

[ Reply to This | # ]

Xcode: Accessing Java from Objective C
Authored by: macFanDave on Mar 27, '04 12:07:00PM

The timing of this article is very coincidental. While I've been using ObjC for quite a while, my next project at work requires that I learn Java and I started this week. Naturally, the topic of this article intrigued me.

I followed the instructions as precisely as I could and had only partial success. The first half of main executes fine (the java_util_Vector part), but the HelloBridge section fails.

The "JavaClasses" target builds successfully, but the HelloBridge target gives me the following warning:
[code]Dependency analysis: warning: no rule to process 'HelloBridge.java'[/code]

and then running the code yields this:

[code]
Java HotSpot(TM) Client VM warning: Attempt to guard stack yellow zone failed.
Java HotSpot(TM) Client VM warning: Attempt to guard stack red zone failed.
2004-03-27 10:53:18.050 HelloBridge[2697] Item 1=One item!
2004-03-27 10:53:18.086 HelloBridge[2697] *** Uncaught exception: <java/lang/ClassNotFoundException> HelloBridge

HelloBridge has exited due to signal 5 (SIGTRAP).
[/code]

(Note that the statement that executed at 10:53:18.050 shows that the java_util_Vector part succeeded.)

Can you tell from these outputs what went wrong? If not, I'd be happy to send you the whole project for closer examination.

Thank you.
Dave



[ Reply to This | # ]
Xcode: Accessing Java from Objective C
Authored by: joadan on Mar 28, '04 12:59:15PM

I think you forgot step 8, you must build the java target before you build the main target.

Joakim

---
jocke



[ Reply to This | # ]
Xcode: Accessing Java from Objective C
Authored by: kirankumareffig on Oct 25, '05 06:41:59AM

To my surprise even iam facing the similar problem.
All iam doing is initialising a java class thru Objective -c, and calling a method(that takes NSdictionary as a parmeter) on the created obect. In the java class iam taking a Hashtable as the relative to NSdictionary.

In the java class object, method is being called properly. But the only thing that intriguing me is , the size of the hashtable. It is being displayed as 1782626377.
And iam unable to access the values in the hash table.



[ Reply to This | # ]
Some lines may not be required?
Authored by: Anonymous on Mar 28, '04 12:48:39AM

One thing I have found is that these lines

// Load the Java VM
id vm = NSJavaSetupVirtualMachine();

// Start the Java class loader
NSJavaClassesFromPath(nil, nil, YES, &vm);

don't seem to be necessary in a cocoa application.

At least I don't have them to my knowledge and things seem to work fine. Although that is under Jaguar 10.2 rather than Panther 10.3

Instead I just add a new cocoa java class and type away, then call the methods or create classes as described from objective C.



[ Reply to This | # ]