GithubHelp home page GithubHelp logo

j2objc-contrib / j2objc-gradle Goto Github PK

View Code? Open in Web Editor NEW
139.0 14.0 43.0 1.28 MB

This plugin is no longer actively maintained. J2ObjC Gradle Plugin: enables Java source to be part of an iOS application's build so you can write an app's non-UI code (such as application logic and data models) in Java, which is then shared by Android apps (natively Java) and iOS apps (using J2ObjC), all as part of your usual Android Gradle build.

Home Page: https://github.com/j2objc-contrib/j2objc-gradle

License: Apache License 2.0

Groovy 87.71% Shell 1.61% Java 4.06% Swift 5.62% Objective-C 0.57% Ruby 0.43%

j2objc-gradle's Introduction

Hey! We are looking for new developers to maintain the plugin. Let us know on j2objc-discuss if you are interested. Active development on this plugin is otherwise currently suspended.

J2ObjC Gradle Plugin

The J2ObjC Gradle plugin enables Java source to be part of an iOS application's build so you can write an app's non-UI code (such as application logic and data models) in Java, which is then shared by Android apps (natively Java) and iOS apps (using J2ObjC).

The plugin:

  • Translates your Java source code to Objective-C for iOS (iPhone/iPad) using J2ObjC, an open-source tool from Google
  • Builds Objective-C static libraries and headers ready-to-use in Xcode
  • Runs translated versions of your JUnit tests to ensure your code works in Objective-C form
  • Handles multiple Java projects, external Java libraries [1], and existing Objective-C code you'd like to link in
  • Configures Xcode projects to use your translated libraries, using CocoaPods (optionally)

The plugin is not affiliated with Google but was developed by former Google Engineers and others. Note that the plugin is currently in alpha; we may need to make breaking API changes before the 1.0 release.

License OSX and Linux Build Status Windows Build Status

Home Page: https://github.com/j2objc-contrib/j2objc-gradle

Quick Start Guide

You should start with a clean Java only project without any Android dependencies. It is suggested that the project is named shared. It must be buildable using the standard Gradle Java plugin. Starting with an empty project allows you to gradually shift over code from an existing Android application. This is beneficial for separation between the application model and user interface. It also allows the shared project to be easily used server-side as well.

The Android app, shared Java project and Xcode project should be sibling directories, i.e children of the same root level folder. Suggested folder names are 'android', 'shared' and 'ios' respectively. See the FAQ section on recommended folder structure.

Configure shared/build.gradle for your Java-only project:

// File: shared/build.gradle
plugins {
    id 'java'
    id 'com.github.j2objccontrib.j2objcgradle' version '0.5.0-alpha'
}

dependencies {
    // Any libraries you depend on, like Guava or JUnit
    compile 'com.google.guava:guava:18.0'
    testCompile 'junit:junit:4.11'
}

// Plugin settings; put these at the bottom of the file.
j2objcConfig {
    // Sets up libraries you depend on
    autoConfigureDeps true
    
    // Omit these two lines if you don't configure your Xcode project with CocoaPods
    xcodeProjectDir '../ios'  //  suggested directory name
    xcodeTargetsIos 'IOS-APP', 'IOS-APPTests'  // replace with your iOS targets

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

Finally, make the Android application's android/build.gradle depend on the shared project:

// File: android/build.gradle
dependencies {
    compile project(':shared')
}

For more complex situations like:

, check the FAQ table of contents or see all of the j2objcConfig settings in J2objcConfig.groovy.

Minimum Requirements

The plugin requries modern versions of Gradle and J2ObjC, and assumes the J2ObjC Requirements:

  • Gradle 2.4
  • J2ObjC 0.9.8.2.1 or higher
  • JDK 1.7 or higher
  • Mac workstation or laptop
  • Mac OS X 10.9 or higher
  • Xcode 7 or higher

Applications built with the plugin may target

  • iOS 6.0 or higher
  • OS X 10.6 or higher

J2ObjC Installation

If J2ObjC is not detected when the plugin is first run, on-screen instructons will guide you through installation from your Terminal.

Alternatively: Download the latest version from the J2ObjC Releases. Find (or add) the local.properties in your root folder and add the path to the unzipped folder:

# File: local.properties
j2objc.home=/J2OBJC_HOME

Build Commands

The plugin will output the generated source and libaries to the build/j2objcOutputs directory, run all unit tests, and configure your Xcode project (if you specified one).

It is integrated with Gradle's Java build plugin and may be run as follows:

./gradlew shared:build

Problems

Having issues with the plugin? Please first check the Frequently Asked Questions.

Next, search the Issues for a similar problem. If your issue is not addressed, please file a new Issue, including the following details:

  • build.gradle file(s)
  • contents of Gradle build errors if any
  • version of J2ObjC you have installed

If you are not comfortable sharing these, the community may not be able to help as much. Please note your bug reports will be treated as "Contribution(s)" per the LICENSE.

Mozilla's Bug writing guidelines may be helpful. Having public, focused, and actionable Issues helps the maximum number of users and also lets the maximum number of people help you. Please do not email the authors directly.

FAQ

Please see FAQ.md.

Contributing

See CONTRIBUTING.md.

License

This library is distributed under the Apache 2.0 license found in the LICENSE file. J2ObjC and libraries distributed with J2ObjC are under their own licenses.

Footnotes

[1] where source is appropriately licensed and available

j2objc-gradle's People

Contributors

advaydev1 avatar brunobowden avatar confile avatar danieldickison avatar himamis avatar madvayapiaccess avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

j2objc-gradle's Issues

CocoaPods Library integration

Instead of including source code, switch to linking a prebuilt library and including the library headers.

  1. include j2objc-generated-library.a
  2. add j2objc headers folder to HEADER_SEARCH_PATH
  3. update PROJECT-bridgingheader.h to reference the all the headers within Swift, as defined by an "export interface" sourceSet

@confile - make the changes to output the correct file and then reassign this to...
@advayDev1 - so he can modify the file with the correct output

Fix --build-closure performance exception

I disagree that we should prioritize speed over correctness in the case below (my projects use --build-closure). What are folks opinions' on me getting rid of this conditional and always keeping --build-closure if the user asked for it? @confile @brunobowden

If we later find a way to make this work in all cases, we should make the optimization, but I don't think we should unless it is guaranteed correct.

...
        // add java classpath base to classpath for incremental translation
        // we have to check if translation has been done before or not
        // if it is only an incremental build we must remove the --build-closure
        // argument to make fewer translations of dependent classes 
        // NOTE: TODO there is one case which fails, when you have translated the code
        // make an incremental change which refers to a not yet translated class from a 
        // source lib. In this case due to not using --build-closure the dependent source 
        // we not be translated, this can be fixed with a clean and fresh build
        def translateFlags = "${project.j2objcConfig.translateFlags}"
        if (translatedFiles > 0) {
            translateFlags = translateFlags.toString().replaceFirst("--build-closure","").trim()
        }
...

Use idiomatic sourceSets for all listings of source files

The idiomatic way in Gradle to specify what sources a project is using is to use source sets. Usually 'main' for production code and 'test' for test code.

Currently, source files are found by aggregating globs of .java files, ex:

srcFiles = files(
                        fileTree(dir: projectDir,
                                include: "**/*.java",
                                exclude: project.relativePath(buildDir)) +
                        fileTree(dir: "build/source/apt",
                                include: "**/*.java")
                        )

Instead we should always be using the sourceSets in the project. Currently, we will erroneously find files that are not part of the project build but just happen to be in the directory, miss files the user has added to the source set (specifically generated source directories, which have to be added manually but should not have to be), and causes special casing like the above for apt (this should also allow us to fix #45.).

In addition for test sources:

 // Doesn't use 'buildDir' as missing full path with --no-package-directories flag
                srcFiles = files(fileTree(dir: projectDir, includes: ["**/*Test.java"]))

we should be using the 'test' source set.

Support generated-from-java and hand-migrated ObjC together

@brunobowden continuing our discussion from #56

how have you been tackling it?

btw, the way I'm doing this right now (until we can finish #51), is:

  1. j2objc plugin attached to each of my individual Java projects (let this be JP), each with --build-closure.
    a) translateExcludeClass for entire classes that just don't make any sense in ObjC land and no one depends on.
    b) for libraries I don't control or want to muck too much with, I create a sparse parallel Java source tree which stubs out the methods not compatible with ObjC land. then I add this sparse source tree to the translateSourcepath, while also keeping the original library's jar on the classpath. (or if I have both the original and mine as sources, put them both in the sourcepath, with my overlay first)
  2. a seperate gradle build project (that depends on all of the above ones) with a single task that copies all of the j2objcCopy output directories from projects in list JP into a single output directory. They are copied in reverse order of the gradle project dependencies (i.e. if :appx depends on :libx, :appx's j2objcCopy destDir is copied into the final objc directory, and then :libx's destDir is copied on top of it. this prevents any ill effect from '--build-closure', since the project that 'owns' that source is guaranteed to have the final overwrite for its translated ObjC files).
  3. finally I overlay hand-written objc files in a sparse source tree on top of the output of (2).

I find this to be a somewhat cleaner approach than putting a bunch of OCNI in my code, and it isn't possible for libraries I don't control anyway.

J2objcXcodeTask: Failed to execute

I recently updated to the latest version of the J2objcXcodeTask and got the following error while running gradle j2objcXcode --info:

Executing task ':j2objcXcode' (up-to-date check took 0.0 secs) due to:
  Task has not declared any outputs.
Starting process 'command 'bundle''. Working directory: /Users/mg/Documents/Grails/GGTS3.6.3-SR1-2/test-core Command: bundle exec integratej2objc integrate_source -p /Users/mg/Documents/Grails/GGTS3.6.3-SR1-2/test-core/../Test -x Test.xcodeproj -s ../test-core/build/j2objc -g j2objc-generated -t Test
Successfully started process 'command 'bundle''
Could not locate Gemfile or .bundle/ directory
:j2objcXcode FAILED
:j2objcXcode (Thread[main,5,main]) completed. Took 0.198 secs.

When I replace:

                executable "bundle"

                args "exec"
                args "integratej2objc"
                args "integrate_source"
                args "-p", "${xcodeProjectDir}"
                args "-x", "${xcodeProject}"
                args "-s", "${srcFolder}"
                args "-g", "${xcodeJ2objcGeneratedDir}"
                args "-t", "${xcodeTarget}"

with

                executable "integratej2objc"
                args "integrate_source"
                args "-p", "${xcodeProjectDir}"
                args "-x", "${xcodeProject}"
                args "-s", "${srcFolder}"
                args "-g", "${xcodeJ2objcGeneratedDir}"
                args "-t", "${xcodeTarget}"

It worked without problems.

Issues with J2objcXcodeTask

Thank you for creating this plugin. Just some notes/issues:

  1. The srcDir for this task should be j2objcConfig.destDir not ${buildDir}/j2objc.
  2. What is the parameter -p for? I can't find it here https://github.com/developertown/integratej2objc.
  3. The source directory -s should be relative to j2objcConfig.xcodeProjectDir.
  4. The parameter -g is the group path inside Xcode project, not a directory as this name suggests xcodeJ2objcGeneratedDir.

Unable to include resources for unit tests run via the test runner binary

The j2objc documentation describes how to includes resources within an Xcode project at https://github.com/google/j2objc/wiki/Java-Resources and explains why it is necessary when using package prefixes and reflection calls like Class.forName. However, the converted tests generated by this gradle plugin are run via a test runner binary and there doesn't appear to be a way to include that package prefix resource in order for those tests to pass. I'm using mockito because it is already included and translated by j2objc but some of the calls when setting up mocks use Class.forName and those are failing, presumably because of the package prefix issue described on the wiki page referenced above.

Are there any alternatives other than not using mocks for the tests?

Automatically setup for advanced Cycle Finder usage

To use cycle finder I do:

cycleFinderFlags "--whitelist /Applications/J2Objc/j2objc-sorce/jre_emul/cycle_whitelist.txt --sourcefilelist /Applications/J2Objc/j2objc-sorce/jre_emul/build_result/java_sources.mf"

In the latest source I could not find

j2objc-sorce/jre_emul/build_result/java_sources.mf

anymore. So I use an old version.

@brunobowden How do you handle this?

Add Skip Test flag

We need a flag like we have for skipping the cycle finder to skip the tests.

Convert to a buildable Gradle plugin

It's pretty easy to do, and I can do it - but do y'all want that?
It is slightly more annoying to rapidly develop, but if it is a plugin you'll be able to jar it up and put it on the buildscript classpath of your actual java projects without having to hackily 'apply from'.

I have a number of other locally developed plugins in my toolchain for my main project; I put the plugin projects in both my gradle buildSrc project and as a peer to my regular Java code. That allows them to get built on each gradle run (if anything has changed) while still getting the benefits of being a real plugin.

Multiple java project translation and compilation

I have two projects, say 2 java gradle projects libx and appx. They live under one root gradle project, and therefore appx has a 'compile' dependency on libx. Both libx and appx need to be converted to objc.

Ideally, libx's output directory for j2objcCopy would become an additional include directory for appx's j2objcCompile. In addition, .a files from compiling libx, would be available for linking into appx's j2objcTest phase. libx's jar file would be on the classpath for appx's translation. All the tasks should have inter-project dependencies set correctly (I'm guessing I'm going to need to add a new flavor of dependency like 'j2objc').

This should be all done automatically, without --build-closure (a crutch that is getting less useful as my project graph gets more complicated), and in a hermetic environment (no copying files to j2objc's main /include and /lib directories). Why doesn't this work out of the box and what needs fixing?

  • no way to add additional include directories for j2objcCompile
  • j2objc* tasks between projects do not have dependency edges (i.e. appx:j2objc* depends only on libx:compile not on libx:j2objcTranslate)
  • no way to specify classpath libraries that are not either in $J2OBJC_HOME/lib or in $PROJECT/lib. (gradle doesn't use $PROJECT/lib to save away a peer, dependent project's jar output)
  • j2objc compile tasks don't create/save away .a objects anywhere permanently
  • no way to specify objc .a objects to link that are not in $J2OBJC_HOME/lib
  • input directories for appx's j2objc tasks need to be set so as to include the output directories of libx's j2objc tasks. (this ensures gradle runs the right tasks on file update).

Thoughts? I'm working on figuring this out on my own in my private codebase, if I succeed I'll try to issue a pull request as long as things haven't diverged too far by then.

Prefix files with hyphens in path crash build

Because the matcher pattern on L245 identifies argument values by 'inverse-hyphen' class, paths are interpreted as terminating early. Instead, argument values should continue until whitespace is found.

Example failure when there is a hyphen:

FAILURE: Build failed with an exception.

* Where:
Script '/Users/XX/clean/YY-ZZ/third_party/j2objc-gradle/j2objc.gradle' line: 245

* What went wrong:
Execution failed for task ':ZZ:j2objcTest'.
> java.io.FileNotFoundException: /Users/XX/clean/YY (No such file or directory)

PR incoming.

Flags to configure include directories, libraries, prefix.properties, etc...

As we use gradle objc compilation and cocoa pods, we should not have the user tell us multiple times common attributes like include directories and linked libraries by overriding command lines as flags. Instead provide separate flags for each of these, and then convert those to the command-line as appropriate for each tool in the chain.

Add libraries to J2Objc classpath

I tried to add the realtime-json lib to J2Objc https://github.com/goodow/realtime-json
realtime-json-0.5.5-SNAPSHOT-sources.jar is under ${projectDir}/lib/

Here is my config:

j2objcConfig {
 j2objcHome "/Applications/J2Objc/j2objc-0.9.6" 
 destDir "${projectDir}/../number-incrementer-ios/Classes"

translateFlags "--no-package-directories --prefixes prefixes.properties --mapping method-mappings.properties -use-arc -classpath ${projectDir}/lib/realtime-json-0.5.5-SNAPSHOT-sources.jar"

compileFlags "-ObjC -ljre_emul"

translateJ2objcLibs "guava-14.0.1.jar", "javax.inject-1.jar", "jsr305-3.0.0.jar"

filenameCollisionCheck = true
    testExecutedCheck = false

}

I does not compile (gradle j2objcTranslate). I get the following errors:

Script '/Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/j2objc.gradle' line: 328

* What went wrong:
Execution failed for task ':j2objcTranslate'.
> Process 'command '/Applications/J2Objc/j2objc-0.9.6/j2objc'' finished with non-zero exit value 1

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':j2objcTranslate'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
    at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51)
    at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
    at org.gradle.launcher.Main.doAction(Main.java:33)
    at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
    at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
Caused by: org.gradle.process.internal.ExecException: Process 'command '/Applications/J2Objc/j2objc-0.9.6/j2objc'' finished with non-zero exit value 1
    at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:365)
    at org.gradle.process.internal.DefaultExecAction.execute(DefaultExecAction.java:31)
    at org.gradle.api.internal.file.DefaultFileOperations.exec(DefaultFileOperations.java:151)
    at org.gradle.api.internal.project.AbstractProject.exec(AbstractProject.java:792)
    at org.gradle.api.internal.project.AbstractProject.exec(AbstractProject.java:788)
    at org.gradle.api.Project$exec$4.call(Unknown Source)
    at J2objcTranslateTask.translate(/Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/j2objc.gradle:328)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:579)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:562)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
    ... 44 more


BUILD FAILED

I suppose there is something wrong with my declaration of classpath?

Custom dependencies

Hi Bruno,
I'm trying to use the plugin but i find I need something more, in my case I have 2 modules: presentation and domain, Presentation depends on domain so I have in my build.gradle on presentation:

j2objcConfig {
    j2objcHome parent.ext.j2objcPath
    destDir iOsProjectPath + 'Presentation'
    testExecutedCheck false
}

But when I try to execute j2objcCopy it just crashes because does not find something of the classes that are on domain, I think I need to configure the classpath but there is no option to configure "j2objcConfig" with this, any hints?

Thanks.

Auto generated BridgingHeader with Pod task

I found, asking the guys from cocoapods, that you can only have one BridgingHeader pre tXcode target.

Thus we should and cannot generate a bridging header in our pod file because a use might want to control his bridging header.

I check if there is another solution for header import but for now there is none.

following instructions but getting an error with simple gradle file.

I'm following the instructions. Using the latest j2objc 0.97 gradle 2.3 Mac OSX 10.9 java version "1.7.0_76"

I'm using a simple gradle file. Just a few java classes & Interfaces. the only dependencies are mockito and junit.

I did not edit the j2objc.gradle file as the instructions did not say to do so.

I'm getting the error:

gradle --stacktrace j2objcTranslate

  • Where:
    Script '/Users/mattpease/IdeaProjects/clean_architecture_tests/j2objc.gradle' line: 161

  • What went wrong:
    A problem occurred evaluating script.

    Failed to apply plugin [class 'j2objc']
    Could not create an instance of type J2objcPluginExtension_Decorated.

  • Try:
    Run with --info or --debug option to get more log output.

  • Exception is:
    org.gradle.api.GradleScriptException: A problem occurred evaluating script.
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:54)

My build.gradle
apply plugin: 'java'

sourceCompatibility = 1.7
version = '1.0'

repositories {
mavenCentral()
}

dependencies {
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
}

test {
testLogging {
events "passed", "skipped", "failed"
}

testLogging.showStandardStreams = true

}

apply from: 'j2objc.gradle'

j2objcConfig {
// MODIFY to where your unzipped j2objc directory is located
// NOTE download the latest version from: https://github.com/google/j2objc/releases
j2objcHome "/javalibs/j2objc-0.9.7"

// MODIFY to where generated objc files should be put for Xcode project
// NOTE these files should be checked in to the repository and updated as needed
// NOTE this should contain ONLY j2objc generated files, other contents will be deleted
destDir "${projectDir}/j2objc-generated"
}

Auto Resolve Dependencies

When using:

translateClassPaths "json-20140107.jar", "javax.inject-1.jar",
translateSourcepaths "some-sources.jav"

the dependencies should be resolved automatically.

Bug report mechanism

When a failure occurs in any step, we should dump some standard info to the error logs:

  • version of j2objc you are running
  • version of clang toolchain
  • location of j2objc home
  • version of j2objc-gradle (if we do release tags)

Then we can have users paste that info into any bug report.

gradle j2objcTranslate Task Configuration

I tried to add the realtime-json lib to J2Objc https://github.com/goodow/realtime-json
realtime-json-0.5.5-SNAPSHOT-sources.jar is under ${projectDir}/lib/

Here is my build.gradle config:

j2objcConfig {
j2objcHome "/Applications/J2Objc/j2objc-0.9.6"
destDir "${projectDir}/../number-incrementer-ios/Classes"

translateFlags "--no-package-directories --prefixes prefixes.properties --mapping method-mappings.properties -use-arc -classpath ${projectDir}/lib/realtime-json-0.5.5-SNAPSHOT-sources.jar"

compileFlags "-ObjC -ljre_emul"

translateJ2objcLibs "guava-14.0.1.jar", "javax.inject-1.jar", "jsr305-3.0.0.jar"

filenameCollisionCheck = true
testExecutedCheck = false
}

Running translation:

gradle j2objcTranslate

Leats to the following errors:

error: /Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/src/main/java/com/example/incrementer/shared/JSNIExample.java:3: The import com.goodow.realtime.json.JsonObject cannot be resolved
error: /Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/src/main/java/com/example/incrementer/shared/JSNIExample.java:14: JsonObject cannot be resolved to a type

This looks like my configuration is wrong.

Given an external library mylib-source.jar

What is the minimal configuration needed to make this lib working with gradle j2objcTranslate?

Better error logging

Right now if translation or something else fails, you get the whole process output dumped and have to use scrollback to find your mistake. I will add to the end of the output a copy of any lines that begin with 'error: '

--classpath flags should be combined to one

I recently get the following error while translating my code:

[ERROR] [system.err] warning: could not find source path for

I raised an Issue and I got the answer that I should merge all classpath flags into one because j2objc does support only one flag.

@brunobowden Do you have an idea how to do that?

Unit Testing for Plugin

This is going to be needed for more external contributors.

@advayDev1 - please set up initial example test, then reassign to me and I'll build out the tests for all the other tasks

Incremental Translation

We should find a way to perform incremental translation. I.e.,

  1. Check which Java files have changed.
  2. Translate only the Java files which have changed.

Gradle projects lacking sourceSets will not compile

We've assumed Java plugin (and its derivatives, like Groovy plugin) usage, which for example use sourceSets. Where we use Java plugin convention by default, we should provide a way to skip that default by providing flags.

As reported by @maxbritto in #48.

At minimum we should allow overriding of the java, test, and resource source directories.

Handle versioning of underlying libraries

Sub-issue from #61

I wrote:

One more thing, with the upcoming release of j2objc, we're going to have to deal with versioning (I'm using the master build of j2objc myself because I need some of the latest features).

Namely we will have with (updated) version numbers:
guava-18.0.jar
hamcrest-core-1.3.jar

So either automatic discovery of the right paths is needed, or we need no default and demand the developer tell us, or some kind of setting per j2objc release (or, couple j2objc-gradle releases with specific releases of j2objc).

Translation fails on use of hamcrest libraries

error: /SOMETHING/SomethingTest.java:75: The type org.hamcrest.Matcher cannot be resolved. It is indirectly referenced from required .class files

Easy to fix just in my project, but since hamcrest is part of the default set of jars in the j2objc/lib directory, I was thinking of adding it to both translateJ2objcLibs and compileFlags. Thoughts?

Style Guidelines for CONTRIBUTING.md

Start developing style guidelines for the project. Ideally based of some existing style guidelines, which are extended for this particularly use case.

  • return statements
  • project.j2objcConfig access and @input and @output connections
  • project.with

Presubmit Command

Instructions on how to run the unit tests and perhaps lint tests before submitting PRs.

CycleFinderMaxCycles setting to fail build when more cycles found

Cycle Finder Task Exit with Failure. I am not sure if this is fixable, but so far I had the same problem when I created the cycle finder task.

Works correct but gives a Failure output.

BUILD SUCCESSFUL

Total time: 3.293 secs
http-server:TestJ2Objc mg$ gradle j2objcCycleFinder
:addAptCompilerArgs
:compileJava
:processResources UP-TO-DATE
:classes
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:j2objcCycleFinder

***** Found reference cycle *****
NumberIncrementer -> (field x with type JSNIExample)
JSNIExample -> (field x with type NumberIncrementer)
----- Full Types -----
Lcom/example/incrementer/shared/NumberIncrementer;
Lcom/example/incrementer/shared/JSNIExample;

1 CYCLES FOUND.
:j2objcCycleFinder FAILED

FAILURE: Build failed with an exception.

* Where:
Script '/Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/j2objc.gradle' line: 277

* What went wrong:
Execution failed for task ':j2objcCycleFinder'.
> Process 'command '/Applications/J2Objc/j2objc-0.9.6/cycle_finder'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 17.552 secs

j2objcTranslate Task caches old files

I tried to use google AutoFactory (https://github.com/google/auto/tree/master/factory) here is the file I translated:

@AutoFactory(className="SomeClassFactory")
public class SomeClass {

    public final String type;
    public final String name;

    public SomeClass(@Provided String type, String name) {
        this.type = type;
        this.name = name;
    }

}

And here is my build gradle file:

apply plugin: 'java'
apply plugin: 'apt'
apply plugin: 'eclipse'
apply from: 'j2objc.gradle'

sourceCompatibility = 1.7
version = '1.0'

eclipse {
    classpath {
       downloadSources=true
       downloadJavadoc=true
    }
}

buildscript {
    repositories {
        mavenCentral()
        jcenter()
        maven {
            url "https://oss.sonatype.org/content/repositories/snapshots/"
        }
    }
    dependencies {
        classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
        classpath 'com.jimdo.gradle:gradle-apt-plugin:0.5-SNAPSHOT'
    }
}

sourceSets {
    apt{
        java{
            srcDir 'build/source/apt'
        }
    }
}

dependencies {
    apt 'com.google.auto.factory:auto-factory:0.1-beta1'

    compile 'com.google.guava:guava:14.0.1'
    compile 'javax.inject:javax.inject:1'

    compile name: 'j2objc_annotations'
    compile 'com.google.auto.factory:auto-factory:0.1-beta1'
    compile 'com.google.auto.factory:auto-factory:0.1-beta1:sources'
}

repositories {
    flatDir {
        dirs 'lib'
    }
}

task createWrapper(type: Wrapper) {
    gradleVersion = '2.2.1'
}

j2objcConfig {
  generatedSourceDir "${projectDir}/build/source/apt"
 j2objcHome "/Applications/J2Objc/j2objc-0.9.6"
 destDir "${projectDir}/../number-incrementer-ios/Classes"

translateFlags """--no-package-directories --prefixes prefixes.properties -use-arc
        -classpath ${projectDir}/lib/auto-factory-0.1-beta1.jar:${projectDir}/lib/auto-service-1.0-rc1.jar:${projectDir}/lib/javax.inject-1.jar:${projectDir}/lib/guava-16.0.jar:${projectDir}/lib/javawriter-2.4.0.jar:${projectDir}/lib/dagger-1.2.0.jar"""

compileFlags "-ObjC -ljre_emul"

translateJ2objcLibs "jsr305-3.0.0.jar"

filenameCollisionCheck = true
    testExecutedCheck = false
    cycleFinder = false
    cycleFinderFlags "--whitelist /Applications/J2Objc/j2objc-sorce/jre_emul/cycle_whitelist.txt --sourcefilelist /Applications/J2Objc/j2objc-sorce/jre_emul/build_result/java_sources.mf"
}   

When I do gradle j2objcTranslatethe first time it works without any errors. Then I created new java classes and deleted the SomeClass.javafile. SomeClass is not referenced in any other file. When I do gradle j2objcTranslate again all the files are translated correctly but there are errors:

translating /Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/src/main/java/com/example/incrementer/shared/SomeClassB.java
translating /Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/src/main/java/com/example/incrementer/shared/Test.java
translating /Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/src/main/java/com/example/incrementer/shared/TestImpl.java
translating /Users/mg/Documents/Grails/GGTS3.6.2/TestJ2Objc/src/main/java/com/example/incrementer/shared/dagger/ApplicationModule.java
translating /tmp/annotation_processing/com/example/incrementer/shared/SomeClassFactory.java
error: /tmp/annotation_processing/com/example/incrementer/shared/SomeClassFactory.java:13: SomeClass cannot be resolved to a type
error: /tmp/annotation_processing/com/example/incrementer/shared/SomeClassFactory.java:14: SomeClass cannot be resolved to a type
translating /tmp/annotation_processing/com/example/incrementer/shared/SomeClassFactoryA.java
error: /tmp/annotation_processing/com/example/incrementer/shared/SomeClassFactoryA.java:10: SomeClassA cannot be resolved to a type
Translated 4 files: 4 errors, 0 warnings
error: /tmp/annotation_processing/com/example/incrementer/shared/SomeClassFactoryA.java:11: SomeClassA cannot be resolved to a type
Translated 0 methods as functions
:j2objcTranslate FAILED

FAILURE: Build failed with an exception.

It tries to translate files that does not exist anymore like the following:

/tmp/annotation_processing/com/example/incrementer/shared/SomeClassFactory.java

The old files must be stored in a cache somewhere.
Do you have any idea what is going on here?

Annotation Processors support improvements

Since we did the following:

tasks.create(name: "j2objcTranslate", type: J2objcTranslateTask,
                    dependsOn: 'j2objcCycleFinder') {
                description "Translates all the java source files in to Objective-C using j2objc"
                srcFiles = files(
                        fileTree(dir: projectDir,
                                include: "**/*.java",
                                exclude: project.relativePath(buildDir)) +
                        fileTree(dir: "build/source/apt",
                                include: "**/*.java")
                        )
                destDir = file("${buildDir}/j2objc")
            }

The generatedSourceDir for the translate task is fixed to "build/source/apt". We have to access the exension generatedSourceDir when creating j2objcTranslate otherwise we do not get the correct folder.

Support native objc Gradle building

I don't use Xcode directly**, instead I prefer to use the Gradle wrapper for Xcode clang toolchain.
See https://docs.gradle.org/current/userguide/nativeBinaries.html

All functionality (that I need at least) of both j2objcc and Xcode pods can be done in Gradle directly. So I'm basically using the j2objcTranslate functionality, and then doing the rest in gradle (without j2objcTest or xcode pods). My current setup is at:
https://gist.github.com/advayDev1/636f34fa80164645e205
This sets up normal Gradle tasks for building my objc libraries, building test executables, and running tests.

I think folks might want to use Xcode pods or Gradle builds, and the core plugin probably should not enforce either. Neither actually are very coupled to j2objc, which is purely translation. I propose we have a tools/ subdirectory or similar that supports pods and gradle native builds, so users can choose what they want.

** For many reasons, most importantly:

  • Xcode doesn't handle non-flat source directories very well.
  • I prefer to use one build toolchain (and one IDE when needed, IDEA/Android Studio) without denormalization/duplication of configuration.
  • Using a single Gradle build ensures a single presubmit/build command builds and tests all platforms and all flavors of my projects.

Cycle Finder Task

I created a cycle Finder Task:

class J2objcCycleFinderTask extends DefaultTask {

    @InputFiles FileCollection srcFiles
    @OutputFile File destFile

    @TaskAction
    def start() {

        println "Start"

        def isWindows = J2objcUtils.isWindows()
        def j2objcHome = J2objcUtils.j2objcHome(getProject())
        def cycleFinderExec = j2objcHome + "/cycle_finder"
        def firstArgs = ""
        if (isWindows) {
            j2objcExec = "java"
            // "-Xbootclasspath:${j2objcHome}/lib/jre_emul.jar"
            firstArgs = "-jar ${j2objcHome}/lib/cycle_finder.jar"
        }

        // clear the destFile
        project.delete destFile

        srcFiles = J2objcUtils.fileFilter(srcFiles,
                project.j2objcConfig.translateIncludeRegex,
                project.j2objcConfig.translateExcludeRegex)

        if (project.j2objcConfig.filenameCollisionCheck) {
            J2objcUtils.filenameCollisionCheck(srcFiles)
        }

        print "cycleFinderExec: "+cycleFinderExec


//      def stdout = new ByteArrayOutputStream()
        project.exec {
            executable cycleFinderExec

//                args firstArgs.split()

            args "-sourcepath", project.file("src/main/java").path

            project.j2objcConfig.translateJ2objcLibs.each { library ->
                def libPath = J2objcUtils.j2objcHome(getProject()) + "/lib/" + library
                args "-classpath", project.file(libPath).path
            }

//                args "${project.j2objcConfig.translateFlags}".split()

            srcFiles.each { file ->
                args file.path
            }

            standardOutput = stdout
            destFile << stdout
        }

    }

}

and append in class j2objc implements Plugin<Project>:

            tasks.create(name: "j2objcCycleFinder", type: J2objcCycleFinderTask) {
                description "Run the cycle_finder tool on all Java source files"
                outputs.upToDateWhen { false }  // make the task run on every execution
                srcFiles = files(
                    fileTree(dir: projectDir,
                            include: "**/*.java",
                            exclude: project.relativePath(buildDir)))
                destFile = file("${buildDir}/j2objc_cycleFinderResult")
            }

The command is executed correctly but the task fails. May be this helps you. It was designed to write the output in the destFile so one can see the printout of the cycle finder.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.