1

We use J2ObjC and are trying to make the switch to Xcode 6's dynamic frameworks in order to incorporate Swift into the project. Simply adding use_frameworks! to our Podfile works great in the case where we're just using J2ObjC, but the problem comes when adding other libraries that reference it.

In this particular example, I have two pods in my Podfile, J2ObjC and any other pod that uses it. Let's call it whatever. The current J2ObjC podspec can be found here. Here's the podspec for whatever:

Pod::Spec.new do |s|
  s.ios.deployment_target = '8.0'
  s.requires_arc = true
  s.source_files = '**/*.{h,m}'
  s.dependency 'J2ObjC'
  s.xcconfig = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/J2ObjC/dist/include',
  'LIBRARY_SEARCH_PATHS' => '${PODS_ROOT}/J2ObjC/dist/lib' }
end

So far so good. Now, if I want to reference a Java class, say JavaUtilArrayList inside my app, I can do that.

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    JavaUtilArrayList *arrayList = [[JavaUtilArrayList alloc]init];
    NSString *whatever = @"o hai";
    [arrayList addWithId:[whatever copy]];
    NSLog(@"%@", arrayList);
}

Awesome, J2ObjC works inside my main target. But if I try to do the same thing inside whatever, even though the compiler thinks everything is fine (J2ObjC imports work, classes are available, etc.), I get a linker error:

#import "SomeClass.h"
#import "java/util/ArrayList.h"

@implementation SomeClass    // Inside 'whatever'
-(JavaUtilArrayList *)arrayList {
    NSString *aThing = @"o hai";
    JavaUtilArrayList *myList = [[JavaUtilArrayList alloc]init];
    [myList addWithId:aThing];
    NSLog(@"%@", myList);
    return myList;
}

leads to:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_JavaUtilArrayList", referenced from:
      objc-class-ref in SomeClass.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I've been going crazy reading the CocoaPods guides, man ld, and the J2ObjC guides and am still not getting anywhere. Has anyone built a pod on top of J2ObjC and successfully installed it using use_frameworks!? Any advice would be super appreciated.

jefflovejapan
  • 2,047
  • 3
  • 20
  • 34
  • Given that dynamic frameworks are so new, I'm not surprised that there are issues with it. I've done all my development in Swift code only, with bridging headers to access to the j2objc translated code and that's worked well. I don't understand CocoaPods or Xcode well enough to offer a fix for this. – brunobowden Jul 15 '15 at 08:44
  • @brunobowden Thanks. Are you working with any pods, either your own or anyone else's, that depend on J2ObjC and build with frameworks? – jefflovejapan Jul 15 '15 at 15:25
  • I don't work with other pods at the moment, though I'm looking for someone that might have insight on a related bug: https://github.com/j2objc-contrib/j2objc-gradle/issues/273#issuecomment-121526373 – brunobowden Jul 15 '15 at 18:44

1 Answers1

0

Any symbol begging with "_OBJC_CLASS" is from J2ObjC. If it begins "_OBJC_CLASS_$_Java" then it's from the Java Runtime Environment (JRE). If it doesn't have "$_Java" then see this answer.

The linker is missing out the libjre_emul.a library from J2ObjC (JRE emulation library). You need to configure the following:

  1. LIBRARY_SEARCH_PATHS: J2OBJC_HOME/lib
  2. OTHER_LDFLAGS: -l"jre_emul"

I'd suggest trying out the J2ObjC Gradle Plugin as it will automatically configure this for you. Alternatively, see the Xcode Build Rules.

Community
  • 1
  • 1
brunobowden
  • 1,492
  • 19
  • 37