diff --git a/.gitignore b/.gitignore
index 6d3f90f..3559f19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,112 @@
+
+# Created by https://www.gitignore.io/api/gradle,intellij+all
+# Edit at https://www.gitignore.io/?templates=gradle,intellij+all
+
+### Intellij+all ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij+all Patch ###
+# Ignores the whole .idea folder and all .iml files
+# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
+
+.idea/
+
+# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
+
+*.iml
+modules.xml
+.idea/misc.xml
+*.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+### Gradle ###
 .gradle
-build
+build/
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# Cache of project
+.gradletasknamecache
+
+# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
+# gradle/wrapper/gradle-wrapper.properties
+
+### Gradle Patch ###
+**/build/
+
+# End of https://www.gitignore.io/api/gradle,intellij+all
+gradle
 JavaAppLauncher
diff --git a/build.gradle b/build.gradle
index 7b5443d..5b74f84 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,11 +1,15 @@
+import org.gradle.internal.jvm.Jvm
+
 buildscript {
     repositories {
         jcenter()
         mavenCentral()
+        mavenLocal()
     }
+
     dependencies {
         classpath 'org.codehaus.groovy:groovy-all:2.3.6'
-        classpath 'nu.studer:gradle-plugindev-plugin:1.0.3'
+        classpath 'nu.studer:gradle-plugindev-plugin:1.0.12'
     }
 }
 
@@ -17,19 +21,18 @@ apply plugin: 'nu.studer.plugindev'
 group = 'com.github.cr0'
 
 // find osx sdk
-def osxSDKRoot = new File("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/")
-if (!osxSDKRoot.exists()) throw new GradleException("SDK root does not exist")
 
-def sdk = null
-for (def c : osxSDKRoot.listFiles()) {
-    if (c.name.compareTo("MacOSX10.8.sdk") < 0) continue // fancy ;)
-
-    if (sdk == null) sdk = c.name
-    else if (sdk.compareTo(c.name) < 0) sdk = c.name
+String findMacOSSDKRoot() {
+    def stdoutBuffer = new ByteArrayOutputStream()
+    exec {
+        commandLine "xcrun", "--sdk", "macosx", "--show-sdk-path"
+        standardOutput = stdoutBuffer
+    }
+    return stdoutBuffer.toString().trim()
 }
 
-if (sdk == null) throw new GradleException("No feasible SDK found")
-def osxSDK = new File(osxSDKRoot, sdk)
+def osxSDK = findMacOSSDKRoot()
+if (osxSDK == "") throw new GradleException("No feasible SDK found")
 
 model {
     platforms {
@@ -41,21 +44,34 @@ model {
     buildTypes {
         release
     }
-}
 
-executables {
-    main {
-        baseName "JavaAppLauncher"
+    repositories {
+        libs(PrebuiltLibraries) {
+            javaHeaders {
+                headers.srcDirs "${Jvm.current().javaHome}/include", "${Jvm.current().javaHome}/include/darwin"
+            }
+        }
+    }
+
+    components {
+        JavaAppLauncher(NativeExecutableSpec) {
+            sources {
+                objc {
+                    lib library: 'javaHeaders', linkage: 'api'
+                    source {
+                        srcDirs "src/main/objc"
+                        include "**/*.m"
+                    }
+                }
+            }
+
+        }
     }
 
-    all {
-        binaries.all {
-            if (targetPlatform.operatingSystem.macOsX) {
-                objcCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
-                objcCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include/darwin"
-                objcCompiler.args '-F', "${org.gradle.internal.jvm.Jvm.current().javaHome}/../../"
+    binaries {
+        all {
+            if (toolChain in Clang) {
                 linker.args '-framework', "Cocoa"
-                linker.args '-isysroot', osxSDK.absolutePath
             }
         }
     }
@@ -82,8 +98,8 @@ bintray {
     pkg.repo = 'gradle-plugins'
 }
 
-task copyStub(type: Copy, dependsOn: 'mainExecutable') {
-    from 'build/binaries/mainExecutable/'
+task copyStub(type: Copy, dependsOn: 'JavaAppLauncherExecutable') {
+    from 'build/exe/javaAppLauncher/'
     into 'src/main/resources/com/github/cr0/macAppBundle/'
     outputs.upToDateWhen { false }
 }
diff --git a/gradle.properties b/gradle.properties
index d2757ca..be9eda0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1 +1 @@
-version = 3.1.0
\ No newline at end of file
+version = 3.1.2
\ No newline at end of file
diff --git a/src/main/groovy/com/github/cr0/gradle/macAppBundle/MacAppBundlePlugin.groovy b/src/main/groovy/com/github/cr0/gradle/macAppBundle/MacAppBundlePlugin.groovy
index b91a087..eb1ed4d 100644
--- a/src/main/groovy/com/github/cr0/gradle/macAppBundle/MacAppBundlePlugin.groovy
+++ b/src/main/groovy/com/github/cr0/gradle/macAppBundle/MacAppBundlePlugin.groovy
@@ -241,7 +241,7 @@ class MacAppBundlePlugin implements Plugin<Project> {
         task.description = "Create a dmg containing the .app and optional background image"
         task.group = GROUP
         task.inputs.dir("${-> project.buildDir}/${-> project.macAppBundle.appOutputDir}")
-        task.inputs.property("backgroundImage", { project.macAppBundle.backgroundImage })
+        task.inputs.property("backgroundImage", { project.macAppBundle.backgroundImage }).optional(true)
         task.outputs.file("${-> project.buildDir}/${-> project.macAppBundle.archiveOutputDir}/${-> project.macAppBundle.archiveName}.dmg")
 
         project.afterEvaluate {
diff --git a/src/main/objc/main.m b/src/main/objc/main.m
index b0ce1bb..03b9938 100644
--- a/src/main/objc/main.m
+++ b/src/main/objc/main.m
@@ -27,6 +27,7 @@
 #import <Cocoa/Cocoa.h>
 #include <dlfcn.h>
 #include <jni.h>
+#include <fts.h>
 
 #define JAVA_LAUNCH_ERROR "JavaLaunchError"
 
@@ -67,8 +68,9 @@ typedef int (JNICALL *JLI_Launch_t)(int argc, char ** argv,
 
 int launch(char *, int, char **);
 NSString * findDylib (bool);
-int extractMajorVersion (NSString *vstring)
-;NSString * convertRelativeFilePath(NSString * path);
+int extractMajorVersion (NSString *vstring);
+NSString * convertRelativeFilePath(NSString * path);
+NSString * findFirstFile(NSString * needle, NSString * haystack);
 
 int main(int argc, char *argv[]) {
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -84,7 +86,7 @@ int main(int argc, char *argv[]) {
         result = 0;
     } @catch (NSException *exception) {
         NSAlert *alert = [[NSAlert alloc] init];
-        [alert setAlertStyle:NSCriticalAlertStyle];
+        [alert setAlertStyle:NSAlertStyleCritical];
         [alert setMessageText:[exception reason]];
         [alert runModal];
 
@@ -107,7 +109,7 @@ int launch(char *commandName, int progargc, char *progargv[]) {
     NSDictionary *infoDictionary = [mainBundle infoDictionary];
 
     // Test for debugging (but only on the second runthrough)
-    bool isDebugging = (launchCount > 0) && [[infoDictionary objectForKey:@JVM_DEBUG_KEY] boolValue];
+    bool isDebugging = [[infoDictionary objectForKey:@JVM_DEBUG_KEY] boolValue];
 
     if (isDebugging) {
         NSLog(@"Loading Application '%@'", [infoDictionary objectForKey:@"CFBundleName"]);
@@ -464,7 +466,7 @@ int launch(char *commandName, int progargc, char *progargv[]) {
         NSTask *task = [[NSTask alloc] init];
         [task setLaunchPath:@"/usr/libexec/java_home"];
 
-        NSArray *args = [NSArray arrayWithObjects: @"-v", @"1.7+", nil];
+        NSArray *args = [NSArray arrayWithObjects: @"-v", @"1.7+", @"-F", nil];
         [task setArguments:args];
 
         NSPipe *stdout = [NSPipe pipe];
@@ -499,31 +501,9 @@ int launch(char *commandName, int progargc, char *progargv[]) {
             return nil;
         }
 
-        int version = 0;
-
-        NSRange vrange = [outRead rangeOfString:@"jdk1."];
-
-        if (vrange.location != NSNotFound) {
-            NSString *vstring = [outRead substringFromIndex:(vrange.location)];
-
-            vrange  = [vstring rangeOfString:@"/"];
-            vstring = [vstring substringToIndex:vrange.location];
-
-            version = extractMajorVersion(vstring);
-
-            if (isDebugging) {
-                NSLog (@"Found a Java %@ JDK", vstring);
-                NSLog (@"Looks like major version %d", extractMajorVersion(vstring));
-            }
-        }
-
-        if ( version >= 7 ) {
-            if (isDebugging) {
-                NSLog (@"JDK version qualifies");
-            }
-            return [[outRead stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
-                                    stringByAppendingPathComponent:@"/jre/lib/jli/libjli.dylib"];
-        }
+        NSString *homeDir = [outRead stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+        return findFirstFile(@"libjli.dylib", homeDir);
+        
     }
     @catch (NSException *exception)
     {
@@ -564,3 +544,38 @@ int extractMajorVersion (NSString *vstring)
 NSString * convertRelativeFilePath(NSString * path) {
     return [path stringByStandardizingPath];
 }
+
+NSString * findFirstFile(NSString * needle, NSString * haystack) {
+
+    FTSENT *node = NULL;
+    
+    char *paths[] = {(char*) haystack.UTF8String, NULL};
+    FTS* tree = fts_open(paths, FTS_NOCHDIR | FTS_LOGICAL | FTS_XDEV, NULL);
+    
+    NSString* foundFilePath = NULL;
+    
+    while ((node = fts_read(tree))) {
+        
+        // Skip folders that begin with a dot
+        if (node->fts_level > 0 && node->fts_name[0] == '.') {
+            fts_set(tree, node, FTS_SKIP);
+            
+        } else if (node->fts_info & FTS_F) {
+            
+            if (strcmp(node->fts_name, needle.UTF8String) == 0) {
+                foundFilePath = [NSString stringWithCString: node->fts_path encoding: NSUTF8StringEncoding];
+                break;
+            }
+        }
+    }
+    
+    if (errno) {
+        NSLog (@"fts_read %d", errno);
+    }
+    
+    if (fts_close(tree)) {
+        NSLog (@"fts_close");
+    }
+    
+    return foundFilePath;
+}