How to include .jar file?

2,021 views
Skip to first unread message

Gavin Lee

unread,
Jan 29, 2015, 2:40:39 AM1/29/15
to j2objc-...@googlegroups.com
I use the Xcode Build rules. My project is using an external library, I try to include it.
Here is my build rules:

/Users/admin/Desktop/j2objc-0.9.5/j2objc -d ${DERIVED_FILES_DIR} -sourcepath ${PROJECT_DIR}/ --no-package-directories -classpath "${PROJECT_DIR}/java-lib/commons-math3-3.2.jar" ${INPUT_FILE_PATH};


It is built successfully, but when compile it, those includes throw errors "file not found".

#include "Array2DRowRealMatrix.h"

#include "ArrayRealVector.h"

I go to DerivedSource folder to check and there is no file named Array2DRowRealMatrix.h or ArrayRealVector.h. It seems the .jar is not built or compiled. So how to use a .jar in the project?

Keith Stanger

unread,
Jan 29, 2015, 10:19:57 AM1/29/15
to j2objc-...@googlegroups.com
j2objc does not translate anything that is included in the -classpath. It also cannot translate from .class files. You will have to obtain the sources for the external library (if your jar doesn't already have the .java sources) and include the sources jar in the -sourcepath.

--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gavin Lee

unread,
Jan 30, 2015, 1:08:26 AM1/30/15
to j2objc-...@googlegroups.com
Thanks for your suggestions, Keith. Now I got commons-math3-3.2-sources.jar file, which contains all java source files. So do I have to put it into the same directory with my project java source code? Alternative is add one more path in -sourcepath tag, like the following building rules:

/Users/admin/Desktop/j2objc-0.9.5/j2objc -d ${DERIVED_FILES_DIR} -sourcepath ${PROJECT_DIR}/ "${PROJECT_DIR}/commons-math3-3.2-sources.jar" --no-package-directories ${INPUT_FILE_PATH};

I'm not sure whether I can append two paths after -sourcepath tag. 

Tom Ball

unread,
Jan 30, 2015, 1:36:52 AM1/30/15
to j2objc-...@googlegroups.com
It's just like javac: separate class or source path entries with a ':'. j2objc's front end is the Eclipse Java compiler, which is why the same flags are used.

That will resolve the missing imports from commons-math, but won't translate them, however. To do that, add the --build-closure flag so that any references from your main files get translated if they are found on the source path, like javac does.

--

andrewh...@hotmail.com

unread,
Feb 4, 2015, 9:50:05 AM2/4/15
to j2objc-...@googlegroups.com
I've tried a few variations of this, but I can't get it to work. Obviously, I'm missing something simple...

In my project directory, the Java source files are in "/src/main/java" and I have a separate directory for my 3rd party jars, at the project root: "/libs".

I can translate my project without any errors, when I use the non-source jar files. So I do have a working baseline:

<code>j2objc -use-arc --doc-comments -d ./j2objc-generated -classpath ./libs/*.jar -sourcepath ./src/main/java `find ./src/main/java -name '*.java'`</code>

Of course, I want to translate the sources for my 3rd party jars: commons-lang3-3.3.2-sources.jar and sqlite-jdbc-3.8.7-sources.jar.

So, I removed the non-source jar files and replaced them with their corresponding source jars. Then, I modified my j2objc command to include the "--build-closure" flag, removed the "-classpath" flag (since I'm building the jars from source), and explicitly added my libs directory to the source path using a colon:

<code>j2objc -use-arc --doc-comments --build-closure -d ./j2objc-generated -sourcepath ./src/main/java:./libs/ `find ./src/main/java -name '*.java'`</code>

But I'm getting the error message "The import org.apache.commons cannot be resolved".

Keith Stanger

unread,
Feb 4, 2015, 10:12:39 AM2/4/15
to j2objc-...@googlegroups.com
Your sourcepath entry only has "./libs/". It should reference the actual .jar files as it did in your -classpath flag previously: "./libs/*.jar".

--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discuss+unsubscribe@googlegroups.com.

andrewh...@hotmail.com

unread,
Feb 4, 2015, 11:47:37 AM2/4/15
to j2objc-...@googlegroups.com
Thanks Keith! I tried using this command, but still get the same error:

j2objc -use-arc --doc-comments --build-closure -d ./j2objc-generated -sourcepath ./src/main/java:./libs/*.jar `find ./src/main/java -name '*.java'`

Keith Stanger

unread,
Feb 4, 2015, 11:50:18 AM2/4/15
to j2objc-...@googlegroups.com
It's likely that j2objc fails the *-expansion. Is it too cumbersome to list each of your dependent source jars? (or use some shell scripting to generate the list before passing it to j2objc)

On Wed Feb 04 2015 at 11:47:39 AM <andrewh...@hotmail.com> wrote:
Thanks Keith! I tried using this command, but still get the same error:

j2objc -use-arc --doc-comments --build-closure -d ./j2objc-generated -sourcepath ./src/main/java:./libs/*.jar `find ./src/main/java -name '*.java'`

andrewh...@hotmail.com

unread,
Feb 4, 2015, 12:59:06 PM2/4/15
to j2objc-...@googlegroups.com
I only have 2 jars, so it's not cumbersome. And, totally worth it if it works.

WHICH IT DOES!

For posterity, here's the command that worked for me:

j2objc -use-arc --doc-comments --build-closure -d ./j2objc-generated -sourcepath ./libs/commons-lang3-3.3.2-sources.jar:./libs/sqlite-jdbc-3.8.7-sources.jar:./src/main/java `find ./src/main/java -name '*.java'`

I now have warnings because I have a few classes with an enum as an inner class. Moving the enum to be a public class fixes those warnings.

Thanks again, Keith!

confile

unread,
Apr 4, 2015, 3:17:15 PM4/4/15
to j2objc-...@googlegroups.com, andrewh...@hotmail.com
I have the same problem. I use the build-closure flag which produces warnings of my my source jars. When importing the generated files in Xcode I cannot compile without errors.

Here is a demo project to show the problem: https://github.com/confile/j2objc-inner-classes

Vlad Florin Muscurel

unread,
Apr 6, 2015, 8:38:03 AM4/6/15
to j2objc-...@googlegroups.com
Actually for me after using a similar command, I'm faced with another problem. 
The imports include the path to the file, like in Java (eg: #include "com/example/testproject/test/TestInterface.h")
The problem with this is, it doesn't compile in Xcode, unless I delete what's in front of the class name, after which everything works well.
Any idea why this is?

Tom Ball

unread,
Apr 6, 2015, 10:05:24 AM4/6/15
to j2objc-...@googlegroups.com
We added the --no-package-directories flag to workaround this Xcode limitation, but it only works if all your Java classes have different names (for example, java.util.Date and java.sql.Date can't be transpiled together). If you or a library your project uses have classes that share a name, then the workaround is to put them in separate static library targets in Xcode.

--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.

Vlad Florin Muscurel

unread,
Apr 6, 2015, 11:43:43 AM4/6/15
to j2objc-...@googlegroups.com
Thank you very much for the prompt answer. 
It works fine for me now.

er...@pltech.co.nz

unread,
Apr 9, 2015, 2:19:45 AM4/9/15
to j2objc-...@googlegroups.com
I have a class that uses the slf4j api library, which i translate with no package directories and build closure. It compiles, but during linking it gives the Apple Mach-O Linker error message:
Undefined symbols for architecture arm64:
"_OrgSlf4jLoggerFactory_getLoggerWithNSString_
Is this a problem with how I'm translating it, or is it because the slf4j API library (to my knowledge) doesn't have an implementation? Or is it something else?
I'm building for $ARCHS_STANDARD (arm7 and arm64), with build for active architecture only set to YES.

Keith Stanger

unread,
Apr 9, 2015, 9:15:11 AM4/9/15
to j2objc-...@googlegroups.com
It's hard to guess at what might cause this specific error. The first thing to check is that the Java class containing that method (looks like org/slf4j/LoggerFactory.java) is translated. Then check that it is compiled and linked into your app.

--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discuss+unsubscribe@googlegroups.com.

er...@pltech.co.nz

unread,
Apr 9, 2015, 8:26:28 PM4/9/15
to j2objc-...@googlegroups.com
I can get it to link if I unzip the jar and manually add all the needed java files in it to the compile sources phase in my build phases. It's strange, as the files were being translated, and the imports mustve resolved as it compiled. But it looks like unless I specify the files in compile phases, the linker doesn't link them - trying to use any of the classes' methods results in an error message starting with _OBJC_CLASS_$_. Thoughts?

Tom Ball

unread,
Apr 9, 2015, 8:47:28 PM4/9/15
to j2objc-...@googlegroups.com
Xcode unfortunately has its limits. It's why we still use Make, and have Xcode call it when we need something serious built.

On Thu, Apr 9, 2015 at 5:26 PM <er...@pltech.co.nz> wrote:
I can get it to link if I unzip the jar and manually add all the needed java files in it to the compile sources phase in my build phases. It's strange, as the files were being translated, and the imports mustve resolved as it compiled. But it looks like unless I specify the files in compile phases, the linker doesn't link them - trying to use any of the classes' methods results in an error message starting with _OBJC_CLASS_$_. Thoughts?

er...@pltech.co.nz

unread,
Apr 9, 2015, 9:50:05 PM4/9/15
to j2objc-...@googlegroups.com
Can't be helped then...it looks like I'll probably have to build them to static library targets later anyhow (is there a how-to for this somewhere, by the way? Last time I tried, I think I couldn't get it to find any of the headers in the library). The slf4j api library translates fine now, but doesn't seem to output anything -
System.err.println("SLF4J: " +msg);
is translated to
[((JavaIoPrintStream *) nil_chk(JavaLangSystem_get_err_())) printlnWithNSString:JreStrcat("$$", @"SLF4J: ", msg)];
, but it doesn't seem to output to console?

Tom Ball

unread,
Apr 10, 2015, 1:14:40 AM4/10/15
to j2objc-...@googlegroups.com
System.err.printlln() should work on OS X. It won't on iOS, though, because iOS doesn't have a console. For an alternative, open the jre_emul/JreEmulation project and look at the JRE Unit Tests target. The console magic is in the JRELog classes. Note: there are probably better designs for an iOS console, so it's worth browsing the internet for ideas.

maxime...@gmail.com

unread,
May 7, 2015, 2:35:24 AM5/7/15
to j2objc-...@googlegroups.com
On Friday, April 10, 2015 at 2:47:28 AM UTC+2, Tom Ball wrote:
> Xcode unfortunately has its limits. It's why we still use Make, and have Xcode call it when we need something serious built.
>
>
> On Thu, Apr 9, 2015 at 5:26 PM <er...@pltech.co.nz> wrote:
> I can get it to link if I unzip the jar and manually add all the needed java files in it to the compile sources phase in my build phases. It's strange, as the files were being translated, and the imports mustve resolved as it compiled. But it looks like unless I specify the files in compile phases, the linker doesn't link them - trying to use any of the classes' methods results in an error message starting with _OBJC_CLASS_$_. Thoughts?
>
>
>
> --
>
> You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
>
> To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Hello,
I've reached the same point with the Gson source jar. I managed to translate it right with this command :
"${J2OBJC_HOME}/j2objc" -d ${DERIVED_FILES_DIR} -sourcepath "${PROJECT_DIR}/Rainbow/Model/java:${PROJECT_DIR}/libs/lib/gson-2.3.1-sources.jar" --no-package-directories -use-arc --doc-comments --build-closure -g ${INPUT_FILE_PATH};

And can see the Gson sources being translated along my own java files.
During link, though I have this error :
Undefined symbols for architecture i386:
"_new_ComGoogleGsonGson_init", referenced from:
-[ComDev2aRainbowApiRetrieverDataObjectPromise successWithId:withComDev2aRainbowApiRetrieverResponse:] in DataObjectPromise.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I guess that the Gson translated files are never buildt so it can't find the methods during link, am I right ? How can I work around this ?

Many thanks
Max

Keith Stanger

unread,
May 7, 2015, 10:51:31 AM5/7/15
to j2objc-...@googlegroups.com
Make sure that com/google/gson/Gson.java is translated to Gson.m and that Gson.m is compiled and linked into your app by xcode.

maxime...@gmail.com

unread,
May 7, 2015, 11:09:05 AM5/7/15
to j2objc-...@googlegroups.com
Thanks Keith for your help, I am definitely sure it was translated and I can see the Gson.h and Gson.m. But for the second part, how can I make sure that my Gson.m is compiled and linked into my app by xcode ?

Tom Ball

unread,
May 7, 2015, 12:26:19 PM5/7/15
to j2objc-...@googlegroups.com

Add the translated files to Xcode. To keep your project files separate, I suggest adding them to a different project folder, create a static library target to build them, and then make your app target depend on the library.

maxime...@gmail.com

unread,
May 13, 2015, 2:48:37 AM5/13/15
to j2objc-...@googlegroups.com
It worked by adding/copying back the translated files to XCode, thanks!

Felipe Lima Mota

unread,
Sep 17, 2015, 11:35:03 AM9/17/15
to j2objc-discuss, maxime...@gmail.com
Hello Maxime and Tom, 

I was wonder how did you create this static library. I think this can help me. I already translate all my java code, but I dont know how create a static lib with this.
My translated code has the same package directories in java, but when i add this files in a new xcode project, it doesnt recognize them.

Thanks..

Tom Ball

unread,
Sep 17, 2015, 11:26:54 PM9/17/15
to j2objc-discuss, maxime...@gmail.com
Most jar files only hold .class files, not Java sources. Since j2objc is a source translator, it only works with Java sources. Jars with classfiles can go on the -classpath, but that's just to resolve dependencies in the source files being translated. It's just like javac in that way. Unlike javac, every dependent Java class eventually has to be translated: your Java sources, plus the references they make, plus the references they make, and so on.

That doesn't mean you necessarily need to install each project to get its source files, though. Many projects distribution source jars, which are like regular jars except they hold Java source files in the same directory layout as the regular jars use. Source jars have different naming conventions, but usually have -src or -sources, like foo-sources.jar. Maven central is a good place to look for source jars if it's not obvious from the project sites.

--

Tom Ball

unread,
Sep 17, 2015, 11:28:22 PM9/17/15
to j2objc-discuss, maxime...@gmail.com
One trick to make things easier: if you ask the translator to translate a source jar, it will translate every Java source in that jar. There no need to list all the source file names anywhere.

rizwans...@gmail.com

unread,
Apr 4, 2016, 9:12:51 AM4/4/16
to j2objc-discuss, maxime...@gmail.com
i got this warning: skipping file '/Users/Desktop/DemoApp/J2Objc/myJarFile.jar' (unexpected file type 'archive.jar' in Frameworks & Libraries build phase)
when integrate jar file in xcode7

Tom Ball

unread,
Apr 4, 2016, 11:59:04 AM4/4/16
to j2objc-discuss, maxime...@gmail.com
Uh, why are you adding a jar file? That's an Android artifact, unless your app explicitly opens and reads it using the java.util.jar API. iOS can't run Java class files, which are what jar files normally contain.

If your app does use the java.util.jar API to open that jar, then add it as a resource: go to the target's Build Phases tab, and create a new Copy Files Phase (lick the + icon to create it) with a Resources destination. If you are referencing the jar in your code with a relative directory, like 'new JarFile(new File("foo/bar/mumble.jar"))', then put the relative path ("foo/bar" in this example) in the Subpath box.

rizwans...@gmail.com

unread,
Apr 5, 2016, 6:42:59 AM4/5/16
to j2objc-discuss, maxime...@gmail.com
i got error :The import com.foo.bar.javaClassName cannot be resolved
and Command /bin/sh failed with exit code 130

here is my java source file script
/Users/Home/Desktop/j2objc-1.0.1/j2objc -d ${DERIVED_FILES_DIR} -sourcepath ${PROJECT_DIR}/com/foo/bar ${INPUT_FILE_PATH}

Tom Ball

unread,
Apr 5, 2016, 10:36:08 AM4/5/16
to j2objc-discuss, maxime...@gmail.com
The j2objc is a Java compiler, taking the same -d, -sourcepath, -classpath, -source, etc. arguments as javac does (that's because it reads the sources using Eclipse's Java compiler). Since there isn't anything unique about j2objc's core arguments, try these steps:
  • Run "which javac" to get javac's path, then temporarily update your script to use it instead of j2objc. 
  • Fix the paths until it compiles successfully, then change the javac command back to j2objc, with those same args. 
  • If you can't be javac to work, use the "echo" comand to look at exactly how those environment variables are expanding.
If this is your first experience using Java tools from the command-line, there are lots of good tutorials available on the web.

Rizwan Shaikh

unread,
Apr 7, 2016, 3:41:47 AM4/7/16
to j2objc-...@googlegroups.com
Hi Tom,
i will successfully convert the java file into objective c file.
However in one of my java file use native (JNI) method.
in xcode it will show error like 

Undefined symbols for architecture i386:

  "_Java_com_test_Demo_ft_1createInstance", referenced from:

      _ComTestDemo_ft_createInstance in Demo.o

ld: symbol(s) not found for architecture i386

clang: error: linker command failed with exit code 1 (use -v to see invocation)


this is my Demo.java file

package com.test;

public class Demo {

Demo(){

}    public static final native long ft_createInstance();

}


This is my Demo.m file :

#include "Demo.h"

#include "J2ObjC_source.h"


#line 1 "/Users/Applications/myProject/src/com/test/Demo.java"



#line 3

@implementation ComTestDemo


J2OBJC_IGNORE_DESIGNATED_BEGIN


#line 5

- (instancetype)init {

  ComTestDemo_init(self);

  return self;

}

J2OBJC_IGNORE_DESIGNATED_END



#line 8

+ (jlong)ft_createInstance {

  return ComTestDemo_ft_createInstance();

}


+ (const J2ObjcClassInfo *)__metadata {

  static const J2ObjcMethodInfo methods[] = {

    { "init", "Demo", NULL, 0x0, NULL, NULL },

    { "ft_createInstance", NULL, "J", 0x119, NULL, NULL },

  };

  static const J2ObjcClassInfo _ComTestDemo = { 2, "Demo", "com.test", NULL, 0x1, 2, methods, 0, NULL, 0, NULL, 0, NULL, NULL, NULL };

  return &_ComTestDemo;

}


@end



#line 5

void ComTestDemo_init(ComTestDemo *self) {

  NSObject_init(self);

}



#line 5

ComTestDemo *new_ComTestDemo_init() {

  ComTestDemo *self = [ComTestDemo alloc];

  ComTestDemo_init(self);

  return self;

}



#line 5

ComTestDemo *create_ComTestDemo_init() {

  return new_ComTestDemo_init();

}



#line 8

JNIEXPORT jlong Java_com_test_Demo_ft_1createInstance(JNIEnv *_env_, jclass _cls_);


jlong ComTestDemo_ft_createInstance() {

  return Java_com_test_Demo_ft_1createInstance(&J2ObjC_JNIEnv, ComTestDemo_class_());

}


J2OBJC_CLASS_TYPE_LITERAL_SOURCE(ComTestDemo)


Please help me to solve this.


--
You received this message because you are subscribed to a topic in the Google Groups "j2objc-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/j2objc-discuss/pbrC0qTbQzI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to j2objc-discus...@googlegroups.com.

Tom Ball

unread,
Apr 7, 2016, 10:15:19 AM4/7/16
to j2objc-...@googlegroups.com
There are two options. J2ObjC supports a subset of the Java Native Interface (JNI) if you have already written ft_createInstance() for the JVM or Android. It's a subset because its runtime doesn't have a virtual machine or garbage collector, though, so that may not be an option. Like the JVM and Android, JNI functions have a specified signature starting with JNIEXPORT, and their bodies are written using C, C++, Objective C or Objective C++.

Like GWT, J2ObjC also supports directly embedding native code in special comments, called OCNI. I don't know exactly what your demo's native method needs to do, but here's a generic example with a native version of the "return Demo.class.newInstance();" statement:

    public static final native long ft_createInstance() /*-[
        return [ComTestDemo_class_() newInstance];
    ]-*/;

Notice how the comment is inserted between the end of the native method declaration and its ending semi-colon. A Java compiler will ignore that comment so the source can be shared with JVM and Android apps, while j2objc will create a normal Objective C method.
Message has been deleted

ldt2...@gmail.com

unread,
Oct 23, 2016, 10:42:09 PM10/23/16
to j2objc-discuss
I try to include the itext-2.1.7-sources.jar file with this script :
"${J2OBJC_HOME}/j2objc" --build-closure -d ${DERIVED_FILES_DIR} -sourcepath "${PROJECT_DIR}/" --no-package-directories "${PROJECT_DIR}/Classes/Othello/Engine/itext-2.1.7-sources.jar" ${INPUT_FILE_PATH};


But I got ... cannot be resolve to a type.

Please help me to build with this jar!
Detail :
http://stackoverflow.com/questions/40209680/j2objc-with-source-jar-file

Thanks you so much.

Tom Ball

unread,
Oct 24, 2016, 12:43:59 PM10/24/16
to j2objc-discuss
Try removing the last ${INPUT_FILE_PATH}. j2objc's flags are modeled after javac's (to support build tools), so any argument after the last flag is treated as a source file. Since the sources jar holds all the source files, the ${INPUT_FILE_PATH} tells the compiler to compile a directory, which it can't do.

ldt2...@gmail.com

unread,
Oct 26, 2016, 12:17:29 AM10/26/16
to j2objc-discuss
Vào 23:43:59 UTC+7 Thứ Hai, ngày 24 tháng 10 năm 2016, Tom Ball đã viết:
Thank you but I have changed to "${J2OBJC_HOME}/j2objc" --build-closure -d ${DERIVED_FILES_DIR} -sourcepath "${PROJECT_DIR}/" --no-package-directories "${PROJECT_DIR}/Classes/Othello/Engine/itext-2.1.7-sources.j‌​ar";
The build errors are still there.
Reply all
Reply to author
Forward
0 new messages