Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically handle third-party libraries #372

Closed
advayDev1 opened this issue Aug 20, 2015 · 21 comments
Closed

Automatically handle third-party libraries #372

advayDev1 opened this issue Aug 20, 2015 · 21 comments

Comments

@advayDev1
Copy link
Contributor

@ph1lb4 - could you repost your emailed question re: translating dependent jars here?

Please provide the relevant j2objcConfig, the version of the plugin you are using, your dependencies { } block if possible, and any errors.

@ph1lb4
Copy link

ph1lb4 commented Aug 21, 2015

We have the following dependencies:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'joda-time:joda-time:2.7'
    compile 'com.google.code.gson:gson:2.3.1'
}

And I included them as stated by you in another post with:

translateClasspaths project.sourceSets.main.compileClasspath.getAsPath()

Everything translates fine, but when it comes to compiling the following problem occurs:

/model/network/JsonResponseHandler.m:7:10: fatal error: 'com/google/gson/JsonElement.h' file not found
#include "com/google/gson/JsonElement.h"
         ^
1 error generated.

Do you know how to fix this? I also read that you are planing on automating this in next versions, which will be really convenient!

The relevant parts:

plugins {
    id 'idea'
    id 'java'
    id 'com.github.j2objccontrib.j2objcgradle' version '0.4.0-alpha'
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'joda-time:joda-time:2.7'
    compile 'com.google.code.gson:gson:2.3.1'
}

j2objcConfig {
    xcodeProjectDir '../ios'  // Xcode workspace directory (suggested directory name)
    xcodeTarget 'IOS-APP'     // iOS app target name (replace with existing app name)

    translateClasspaths './libs/bsh-2.0b4.jar'
    translateClasspaths project.sourceSets.main.compileClasspath.getAsPath()

    translateArgs '--prefixes', 'prefixes.properties'

    finalConfigure()          // Must be last call to configuration
}

@advayDev1
Copy link
Contributor Author

  1. you need the source jars for gson joda and bsh as well; add those with translateSourcepaths
  2. then add this line above finalConfigure:
    translateArgs '--build-closure'

that will translate gson joda and bsh as well.

@ph1lb4
Copy link

ph1lb4 commented Aug 24, 2015

Does that mean it is not possible to use dependencies? Because the best thing about dependencies is that I don't have to worry about the jar files.

@advayDev1
Copy link
Contributor Author

How dependencies must be provided is a function of j2objc not this plugin. From j2objc's home page:
"Developers must have source code for their Android app, which they either own or are licensed to use." (http://j2objc.org/)

j2objc must have the source code for everything that needs to be translated into objective-c. j2objc happens to provide, for convenience, pre-translated versions of a few libraries like the JRE, junit, guava. But for gson, joda, bsh, etc. you'll need to provide the source.

Or maybe you're asking: if you have and can use the source jars, does setting dependencies { } work automatically with this plugin? Not yet - that's future work. For now you have to set translateSourcepaths.

@advayDev1
Copy link
Contributor Author

@jjroloff please see this issue and provide any more details you have re: your issue with gson.

@ph1lb4
Copy link

ph1lb4 commented Aug 25, 2015

Actually I meant if it is possible that your plugin automatically downloads the jar file when a dependency is listed in the build script?

@advayDev1
Copy link
Contributor Author

On the roadmap #41 but not yet done. The main issue is resolving duplicates across multiple projects (i.e. when gson is loaded by 3 of your j2objc projects, we don't want to translate/compile/etc. it each time).

For now, you'll have to put a -sources jar in a directory, and use translateSourcepaths.

@advayDev1
Copy link
Contributor Author

@ph1lb4 - I suspect it would be useful for me to add a section to:
https://github.com/j2objc-contrib/j2objc-gradle/blob/master/FAQ.md#how-do-i-setup-dependencies-with-j2objc
for the case of a third-party jar.

We've covered dependencies on prebuilts, native code, and java projects, but not third-party java code in there. I'll send folks a PR (also @jjroloff) and let me know if it is clear.

@ph1lb4
Copy link

ph1lb4 commented Aug 25, 2015

Ok thank you very much, looking forward to this feature!

In the meantime I am still having troubles even with the jar files. My new build script looks as follows:

buildscript {
    repositories {
        mavenCentral()
    }
}

plugins {
    id 'idea'
    id 'java'
    id 'com.github.j2objccontrib.j2objcgradle' version '0.4.2-alpha'
}

repositories {
    mavenCentral()
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

configurations {
    provided
    provided.extendsFrom(compile)
}

sourceSets {
    main { compileClasspath += configurations.provided }
}

j2objcConfig {
    xcodeProjectDir '../ios'  // Xcode workspace directory (suggested directory name)
    xcodeTarget 'IOS-APP'     // iOS app target name (replace with existing app name)

    translateSourcepaths './libs/bsh-2.0b4.jar'
    translateSourcepaths './libs/gson-2.3.1.jar'
    translateSourcepaths './libs/joda-time-2.4.jar'

    translateClasspaths project.sourceSets.main.compileClasspath.getAsPath()

    translateArgs '--prefixes', 'prefixes.properties', '--build-closure'

    finalConfigure()          // Must be last call to configuration
}

However we are still getting the same errors:

.../build/j2objcSrcGen/com/projectr/model/SystemModel.m:7:10: fatal error: 'com/google/gson/JsonObject.h' file not found
#include "com/google/gson/JsonObject.h"
         ^
1 error generated.

.../build/j2objcSrcGen/com/projectr/model/calendar/CalendarEvent.m:8:10: fatal error: 'org/joda/time/DateTime.h' file not found
#include "org/joda/time/DateTime.h"
         ^
1 error generated.

.../build/j2objcSrcGen/com/projectr/model/calendar/Calendar.m:10:10: fatal error: 'org/joda/time/DateTime.h' file not found
#include "org/joda/time/DateTime.h"
         ^
1 error generated.

Do you know how to fix this?

@advayDev1
Copy link
Contributor Author

@ph1lb4

    translateSourcepaths './libs/bsh-2.0b4.jar'
    translateSourcepaths './libs/gson-2.3.1.jar'
    translateSourcepaths './libs/joda-time-2.4.jar'

Are these source jars or classfile jars? If you unzip them do they .java files or .class files?

@advayDev1 advayDev1 self-assigned this Aug 25, 2015
@ph1lb4
Copy link

ph1lb4 commented Aug 25, 2015

If unzipped they all contain .class files

@advayDev1
Copy link
Contributor Author

Yep, you'll need to find source jars for each of those libraries.
If you are using mavenCentral, consider finding them here for example:
http://search.maven.org/#artifactdetails%7Ccom.google.code.gson%7Cgson%7C2.3.1%7Cjar
The links ends with -sources.jar

Put those in a 'srcLibs' directory (to keep them separate from the class jars which you still need), and then change the translateSourcepaths commands to refer to those sources jars.

@ph1lb4
Copy link

ph1lb4 commented Aug 25, 2015

Oh I see, thank you very much for your patience and help, it builds successfully now!

@advayDev1
Copy link
Contributor Author

Awesome! Please take a look at #415 and let me know if it is clear enough for newcomers.
I will resolve this issue fixed once that PR is submitted.

@ph1lb4
Copy link

ph1lb4 commented Aug 25, 2015

Yes, I think the new part in the FAQ makes it much clearer. Should be good for newcomers.

@roisagiv
Copy link

This trick worked for me:

shared/build.gradle

plugins {
  id 'java'
  id 'com.github.j2objccontrib.j2objcgradle' version '0.4.2-alpha'
}

configurations {
  j2objc
}

dependencies {
  compile 'com.eclipsesource.minimal-json:minimal-json:0.9.4'
  j2objc 'com.eclipsesource.minimal-json:minimal-json:0.9.4:sources'

  compile 'com.google.guava:guava:18.0'
  compile 'com.google.j2objc:j2objc-annotations:0.9.8'

  // test libraries
  testCompile 'junit:junit:4.11'
  testCompile 'org.mockito:mockito-core:1.9.5'
}

// Plugin settings:
j2objcConfig {
  xcodeProjectDir '../ios'  // Xcode workspace directory (suggested directory name)
  xcodeTarget 'MyTarget'     // iOS app target name (replace with existing app name)

  translateArgs '-use-arc'
  translateArgs '--build-closure'
  extraObjcCompilerArgs '-fobjc-arc'

  translateJ2objcLibs << 'hamcrest-core-1.3.jar'

  configurations.j2objc.each { translateSourcepaths it.absolutePath.toString() }

  finalConfigure()          // Must be last call to configuration
}

@ph1lb4
Copy link

ph1lb4 commented Aug 25, 2015

What exactly do you mean by trick?
This line:

j2objc 'com.eclipsesource.minimal-json:minimal-json:0.9.4:sources'

@roisagiv
Copy link

this line:
j2objc 'com.eclipsesource.minimal-json:minimal-json:0.9.4:sources'
with this line:
configurations.j2objc.each { translateSourcepaths it.absolutePath.toString() }

@ph1lb4
Copy link

ph1lb4 commented Aug 25, 2015

Ok that is really great! I was just confused because you did not use it for your other dependencies.

@advayDev1
Copy link
Contributor Author

Yes, that's the first part of the solution: use the sources classifier attribute in the Maven coordinate.
As you pointed out, however, it can't be used for all of the libraries, because some of them are included inside j2objc, and you don't want to use the original source for those, since J2ObjC has custom native code for some of them. We need to solve #180 to have a complete solution - that allows the plugin to decide whether a given Maven coordinate should be downloaded from scratch or used from the j2objc dist.

My current simple plan for #41 is to automatically generate a j2objcSource configuration element on j2objcConfig.finalConfigure() that:

  1. For each compile dependency that is a project, use the existing dependsOnJ2objc(proj)
  2. For each compile dependency that matches a set of regexes of libs included in J2ObjC, ignore them
  3. For every compile dependency specified as a Maven coordinate, attach the 'sources' classifier.
  4. Else fail

if any dependencies of type (3) are found, --build-closure is added as well. I should have a PR out later tonight.

If either of you have better ideas, please do tell! Thanks!

advayDev1 added a commit to madvay/j2objc-gradle that referenced this issue Aug 26, 2015
Dependency configuration happens in 2 phases:
- Dependency conversion:
  This converts your compile and testCompile dependencies into
  equivalent j2objcTranslate and j2objcLink dependencies.  Namely
  local jars are copied to j2objcTranslate, external Maven jars are
  converted into their 'sources' form and copied to j2objcTranslate,
  and projects are copied to j2objcLink (they don't need translation).

  This phase is optional and controlled by j2objcConfig.autoConfigureDeps

- Dependency resolution:
  This phase converts j2objcTranslate and j2objcLink deps into
  actual j2objc commands.  Any source jar on j2objcTranslate is
  added to translateSourcepaths with --build-closure.  Any project
  on j2objcLink is added to translateClasspaths and has its final
  j2objc static library linked in to this project's objective c code.

  This phase always runs.  If your dependencies are too complicated
  for the plugin to figure out in the first phase, keep autoConfigureDeps=false,
  and just add the appropriate projets, jars, and libraries here.

Also adds system tests for both project and external Maven dependencies.

j2objc-contrib#180; Fixes j2objc-contrib#41; Fixes j2objc-contrib#372

TESTED=yes
advayDev1 added a commit to madvay/j2objc-gradle that referenced this issue Aug 26, 2015
Dependency configuration happens in 2 phases:
- Dependency conversion:
  This converts your compile and testCompile dependencies into
  equivalent j2objcTranslate and j2objcLink dependencies.  Namely
  local jars are copied to j2objcTranslate, external Maven jars are
  converted into their 'sources' form and copied to j2objcTranslate,
  and projects are copied to j2objcLink (they don't need translation).

  This phase is optional and controlled by j2objcConfig.autoConfigureDeps

- Dependency resolution:
  This phase converts j2objcTranslate and j2objcLink deps into
  actual j2objc commands.  Any source jar on j2objcTranslate is
  added to translateSourcepaths with --build-closure.  Any project
  on j2objcLink is added to translateClasspaths and has its final
  j2objc static library linked in to this project's objective c code.

  This phase always runs.  If your dependencies are too complicated
  for the plugin to figure out in the first phase, keep autoConfigureDeps=false,
  and just add the appropriate projets, jars, and libraries here.

Also adds system tests for both project and external Maven dependencies.

j2objc-contrib#180; Fixes j2objc-contrib#41; Fixes j2objc-contrib#372

TESTED=yes
advayDev1 added a commit to madvay/j2objc-gradle that referenced this issue Aug 26, 2015
Dependency configuration happens in 2 phases:
- Dependency conversion:
  This converts your compile and testCompile dependencies into
  equivalent j2objcTranslate and j2objcLink dependencies.  Namely
  local jars are copied to j2objcTranslate, external Maven jars are
  converted into their 'sources' form and copied to j2objcTranslate,
  and projects are copied to j2objcLink (they don't need translation).

  This phase is optional and controlled by j2objcConfig.autoConfigureDeps

- Dependency resolution:
  This phase converts j2objcTranslate and j2objcLink deps into
  actual j2objc commands.  Any source jar on j2objcTranslate is
  added to translateSourcepaths with --build-closure.  Any project
  on j2objcLink is added to translateClasspaths and has its final
  j2objc static library linked in to this project's objective c code.

  This phase always runs.  If your dependencies are too complicated
  for the plugin to figure out in the first phase, keep autoConfigureDeps=false,
  and just add the appropriate projets, jars, and libraries here.

Also adds system tests for both project and external Maven dependencies.

j2objc-contrib#180; Fixes j2objc-contrib#41; Fixes j2objc-contrib#372

TESTED=yes
advayDev1 added a commit to madvay/j2objc-gradle that referenced this issue Aug 26, 2015
Dependency configuration happens in 2 phases:
- Dependency conversion:
  This converts your compile and testCompile dependencies into
  equivalent j2objcTranslate and j2objcLink dependencies.  Namely
  local jars are copied to j2objcTranslate, external Maven jars are
  converted into their 'sources' form and copied to j2objcTranslate,
  and projects are copied to j2objcLink (they don't need translation).

  This phase is optional and controlled by j2objcConfig.autoConfigureDeps

- Dependency resolution:
  This phase converts j2objcTranslate and j2objcLink deps into
  actual j2objc commands.  Any source jar on j2objcTranslate is
  added to translateSourcepaths with --build-closure.  Any project
  on j2objcLink is added to translateClasspaths and has its final
  j2objc static library linked in to this project's objective c code.

  This phase always runs.  If your dependencies are too complicated
  for the plugin to figure out in the first phase, keep autoConfigureDeps=false,
  and just add the appropriate projets, jars, and libraries here.

Also adds system tests for both project and external Maven dependencies.

j2objc-contrib#180; Fixes j2objc-contrib#41; Fixes j2objc-contrib#372

TESTED=yes
@advayDev1 advayDev1 reopened this Aug 26, 2015
@advayDev1
Copy link
Contributor Author

Proposed solution is #420

@advayDev1 advayDev1 changed the title Error while translating dependent jars Automatically handle third-party libraries Aug 26, 2015
advayDev1 added a commit to madvay/j2objc-gradle that referenced this issue Aug 26, 2015
Dependency configuration happens in 2 phases:
- Dependency conversion:
  This converts your compile and testCompile dependencies into
  equivalent j2objcTranslate and j2objcLink dependencies.  Namely
  local jars are copied to j2objcTranslate, external Maven jars are
  converted into their 'sources' form and copied to j2objcTranslate,
  and projects are copied to j2objcLink (they don't need translation).

  This phase is optional and controlled by j2objcConfig.autoConfigureDeps

- Dependency resolution:
  This phase converts j2objcTranslate and j2objcLink deps into
  actual j2objc commands.  Any source jar on j2objcTranslate is
  added to translateSourcepaths with --build-closure.  Any project
  on j2objcLink is added to translateClasspaths and has its final
  j2objc static library linked in to this project's objective c code.

  This phase always runs.  If your dependencies are too complicated
  for the plugin to figure out in the first phase, keep autoConfigureDeps=false,
  and just add the appropriate projets, jars, and libraries here.

Also adds system tests for both project and external Maven dependencies.

j2objc-contrib#180; Fixes j2objc-contrib#41; Fixes j2objc-contrib#372

TESTED=yes
advayDev1 added a commit to madvay/j2objc-gradle that referenced this issue Aug 26, 2015
Dependency configuration happens in 2 phases:
- Dependency conversion:
  This converts your compile and testCompile dependencies into
  equivalent j2objcTranslation and j2objcLinkage dependencies.  Namely
  local jars are copied to j2objcTranslation, external Maven jars are
  converted into their 'sources' form and copied to j2objcTranslation,
  and projects are copied to j2objcLinkage (they don't need translation).

  This phase is optional and controlled by j2objcConfig.autoConfigureDeps

- Dependency resolution:
  This phase converts j2objcTranslation and j2objcLinkage deps into
  actual j2objc commands.  Any source jar on j2objcTranslation is
  added to translateSourcepaths with --build-closure.  Any project
  on j2objcLinkage is added to translateClasspaths and has its final
  j2objc static library linked in to this project's objective c code.

  This phase always runs.  If your dependencies are too complicated
  for the plugin to figure out in the first phase, keep autoConfigureDeps=false,
  and just add the appropriate projets, jars, and libraries here.

Also adds system tests for both project and external Maven dependencies.

issue j2objc-contrib#180; Fixes j2objc-contrib#41; Fixes j2objc-contrib#372

TESTED=yes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants