Java FFI: extra_java_file annotation use full Java class name
[nit.git] / src / platform / android.nit
index f4b04a6..9bff506 100644 (file)
@@ -42,7 +42,7 @@ class AndroidPlatform
 
        redef fun supports_linker_script do return false
 
-       redef fun toolchain(toolcontext) do return new AndroidToolchain(toolcontext)
+       redef fun toolchain(toolcontext, compiler) do return new AndroidToolchain(toolcontext, compiler)
 end
 
 class AndroidToolchain
@@ -52,30 +52,47 @@ class AndroidToolchain
 
        redef fun compile_dir
        do
-               var android_project_root = "{super}/android/"
+               var android_project_root = "{root_compile_dir}/android/"
                self.android_project_root = android_project_root
-               return "{android_project_root}/jni/nit_compile/"
+               return "{android_project_root}/app/src/main/cpp/"
        end
 
-       redef fun default_outname(mainmodule) do return "{mainmodule.name}.apk"
+       redef fun default_outname do return "{super}.apk"
 
-       redef fun write_files(compiler, compile_dir, cfiles)
+       private fun share_dir: Text
+       do
+               var nit_dir = toolcontext.nit_dir or else "."
+               return (nit_dir/"share").realpath
+       end
+
+       private fun gradlew_dir: Text do return share_dir / "android-gradlew"
+
+       redef fun write_files(compile_dir, cfiles)
        do
                var android_project_root = android_project_root.as(not null)
-               var project = toolcontext.modelbuilder.android_project_for(compiler.mainmodule)
-               var short_project_name = compiler.mainmodule.name.replace("-", "_")
+               var android_app_root = android_project_root/"app"
+               var project = new AndroidProject(toolcontext.modelbuilder, compiler.mainmodule)
                var release = toolcontext.opt_release.value
 
-               var app_name = project.name
-               if app_name == null then app_name = compiler.mainmodule.name
-               if not release then app_name += " Debug"
+               # Compute the root of the project where could be assets and resources
+               var project_root = "."
+               var mpackage = compiler.mainmodule.first_real_mmodule.mpackage
+               if mpackage != null then
+                       var root = mpackage.root
+                       if root != null then
+                               var filepath = root.filepath
+                               if filepath != null then
+                                       project_root = filepath
+                               end
+                       end
+               end
 
-               var app_package = project.java_package
-               if app_package == null then app_package = "org.nitlanguage.{short_project_name}"
-               if not release then app_package += "_debug"
+               # Gather app configs
+               # ---
 
+               var app_name = project.name
+               var app_package = project.namespace
                var app_version = project.version
-               if app_version == null then app_version = "1.0"
 
                var app_min_api = project.min_api
                if app_min_api == null then app_min_api = 10
@@ -84,132 +101,364 @@ class AndroidToolchain
                if app_target_api == null then app_target_api = app_min_api
 
                var app_max_api = ""
-               if project.max_api != null then app_max_api = "android:maxSdkVersion=\"{project.max_api.as(not null)}\""
-
-               # Clear the previous android project, so there is no "existing project warning"
-               # or conflict between Java files of different projects
-               if android_project_root.file_exists then android_project_root.rmdir
-
-               var args = ["android", "-s",
-                       "create", "project",
-                       "--name", short_project_name,
-                       "--target", "android-{app_target_api}",
-                       "--path", android_project_root,
-                       "--package", app_package,
-                       "--activity", short_project_name]
-               toolcontext.exec_and_check(args, "Android project error")
+               if project.max_api != null then app_max_api = "maxSdkVersion  {project.max_api.as(not null)}"
 
-               # create compile_dir
-               var dir = "{android_project_root}/jni/"
-               if not dir.file_exists then dir.mkdir
+               # Create basic directory structure
+               # ---
 
-               dir = compile_dir
-               if not dir.file_exists then dir.mkdir
+               android_project_root.mkdir
+               android_app_root.mkdir
+               (android_app_root/"libs").mkdir
+
+               var android_app_main = android_app_root / "src/main"
+               android_app_main.mkdir
+               (android_app_main / "java").mkdir
+
+               # /app/build.gradle
+               # ---
+
+               # Use the most recent build_tools_version
+               var android_home = "ANDROID_HOME".environ
+               if android_home.is_empty then android_home = "HOME".environ / "Android/Sdk"
+               var build_tools_dir = android_home / "build-tools"
+               var available_versions = build_tools_dir.files
+
+               var build_tools_version
+               if available_versions.is_empty then
+                       print_error "Error: found no Android build-tools, install one or set ANDROID_HOME."
+                       return
+               else
+                       alpha_comparator.sort available_versions
+                       build_tools_version = available_versions.last
+               end
+
+               # Gather ldflags for Android
+               var ldflags = new Array[String]
+               var platform_name = "android"
+               for mmodule in compiler.mainmodule.in_importation.greaters do
+                       if mmodule.ldflags.keys.has(platform_name) then
+                               ldflags.add_all mmodule.ldflags[platform_name]
+                       end
+               end
+
+               # Platform version for OpenGL ES
+               var platform_version = ""
+               if ldflags.has("-lGLESv3") then
+                       platform_version = "def platformVersion = 18"
+               else if ldflags.has("-lGLESv2") then
+                       platform_version = "def platformVersion = 12"
+               end
+
+               # TODO make configurable client-side
+               var compile_sdk_version = app_target_api
+
+               var local_build_gradle = """
+apply plugin: 'com.android.application'
+
+{{{platform_version}}}
+
+android {
+    compileSdkVersion {{{compile_sdk_version}}}
+    buildToolsVersion "{{{build_tools_version}}}"
+
+    defaultConfig {
+        applicationId "{{{app_package}}}"
+        minSdkVersion {{{app_min_api}}}
+        {{{app_max_api}}}
+        targetSdkVersion {{{app_target_api}}}
+        versionCode {{{project.version_code}}}
+        versionName "{{{app_version}}}"
+        ndk {
+            abiFilters 'armeabi-v7a', 'x86'
+        }
+        externalNativeBuild {
+            cmake {
+                arguments "-DANDROID_TOOLCHAIN=gcc"
+            }
+        }
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    externalNativeBuild {
+        cmake {
+            path "src/main/cpp/CMakeLists.txt"
+        }
+    }
+
+    lintOptions {
+       abortOnError false
+    }
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+}
+"""
+               local_build_gradle.write_to_file "{android_project_root}/app/build.gradle"
+
+               # TODO add 'arm64-v8a' and 'x86_64' to `abiFilters` when the min API is available
+
+               # ---
+               # Other, smaller files
+
+               # /build.gradle
+               var global_build_gradle = """
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.0.0'
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+"""
+               global_build_gradle.write_to_file "{android_project_root}/build.gradle"
+
+               # /settings.gradle
+               var settings_gradle = """
+include ':app'
+"""
+               settings_gradle.write_to_file "{android_project_root}/settings.gradle"
+
+               # /gradle.properties
+               var gradle_properties = """
+org.gradle.jvmargs=-Xmx1536m
+"""
+               gradle_properties.write_to_file "{android_project_root}/gradle.properties"
+
+               # Insert an importation of the generated R class to all Java files from the FFI
+               for mod in compiler.mainmodule.in_importation.greaters do
+                       var java_ffi_file = mod.java_file
+                       if java_ffi_file != null then java_ffi_file.add "import {app_package}.R;"
+               end
 
                # compile normal C files
-               super(compiler, compile_dir, cfiles)
+               super
+
+               # ---
+               # /app/src/main/cpp/CMakeLists.txt
 
                # Gather extra C files generated elsewhere than in super
                for f in compiler.extern_bodies do
-                       if f isa ExternCFile then cfiles.add(f.filename.basename(""))
+                       if f isa ExternCFile then cfiles.add(f.filename.basename)
                end
 
+               # Prepare for the CMakeLists format
+               var target_link_libraries = new Array[String]
+               for flag in ldflags do
+                       if flag.has_prefix("-l") then
+                               target_link_libraries.add flag.substring_from(2)
+                       end
+               end
+
+               # Download the libgc/bdwgc sources
+               var share_dir = share_dir
+               if not share_dir.file_exists then
+                       print "Android project error: Nit share directory not found, please use the environment variable NIT_DIR"
+                       exit 1
+               end
+
+               var bdwgc_dir = "{share_dir}/android-bdwgc/bdwgc"
+               if not bdwgc_dir.file_exists then
+                       toolcontext.exec_and_check(["{share_dir}/android-bdwgc/setup.sh"], "Android project error")
+               end
+
+               # Compile the native app glue lib if used
+               var add_native_app_glue = ""
+               if target_link_libraries.has("native_app_glue") then
+                       add_native_app_glue = """
+add_library(native_app_glue STATIC ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
+"""
+               end
+
+               var cmakelists = """
+cmake_minimum_required(VERSION 3.4.1)
+
+{{{add_native_app_glue}}}
+
+
+# libgc/bdwgc
+
+## The source is in the Nit repo
+set(lib_src_DIR {{{bdwgc_dir}}})
+set(lib_build_DIR ../libgc/outputs)
+file(MAKE_DIRECTORY ${lib_build_DIR})
+
+## Config
+add_definitions("-DALL_INTERIOR_POINTERS -DGC_THREADS -DUSE_MMAP -DUSE_MUNMAP -DJAVA_FINALIZATION -DNO_EXECUTE_PERMISSION -DGC_DONT_REGISTER_MAIN_STATIC_DATA")
+set(enable_threads TRUE)
+set(CMAKE_USE_PTHREADS_INIT TRUE)
+
+## link_map is already defined in Android
+add_definitions("-DGC_DONT_DEFINE_LINK_MAP")
+
+## Silence warning
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
+
+add_subdirectory(${lib_src_DIR} ${lib_build_DIR} )
+include_directories(${lib_src_DIR}/include)
+
+
+# Nit generated code
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DANDROID -DWITH_LIBGC")
+
+# Export ANativeActivity_onCreate(),
+# Refer to: https://github.com/android-ndk/ndk/issues/381.
+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
+
+#           name      so       source
+add_library(nit_app   SHARED   {{{cfiles.join("\n\t")}}} )
+
+target_include_directories(nit_app PRIVATE ${ANDROID_NDK}/sources/android/native_app_glue)
+
+
+# Link!
+
+target_link_libraries(nit_app gc-lib
+       {{{target_link_libraries.join("\n\t")}}})
+"""
+               cmakelists.write_to_file "{android_app_main}/cpp/CMakeLists.txt"
+
+               # ---
+               # /app/src/main/res/values/strings.xml for app name
+
+               # Set the default pretty application name
+               var res_values_dir = "{android_app_main}/res/values/"
+               res_values_dir.mkdir
+"""<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">{{{app_name}}}</string>
+</resources>""".write_to_file res_values_dir/"strings.xml"
+
+               # ---
+               # Copy assets, resources in the Android project
+
+               ## Collect path to all possible folder where we can find the `android` folder
+               var app_files = [project_root]
+               app_files.add_all project.files
+
+               for path in app_files do
+                       # Copy the assets folder
+                       var assets_dir = path / "assets"
+                       if assets_dir.file_exists then
+                               assets_dir = assets_dir.realpath
+                               toolcontext.exec_and_check(["cp", "-r", assets_dir, android_app_main], "Android project error")
+                       end
+
+                       # Copy the whole `android` folder
+                       var android_dir = path / "android"
+                       if android_dir.file_exists then
+                               android_dir = android_dir.realpath
+                               for f in android_dir.files do
+                                       toolcontext.exec_and_check(["cp", "-r", android_dir / f, android_app_main], "Android project error")
+                               end
+                       end
+               end
+
+               # ---
+               # Generate AndroidManifest.xml
+
                # Is there an icon?
-               var resolutions = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"]
-               var icon_available = false
+               var resolutions = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi", "anydpi", "anydpi-v26"]
+               var icon_name = null
+               var has_round = false
+
                for res in resolutions do
-                       var path = "res/drawable-{res}/icon.png"
-                       if path.file_exists then
-                               icon_available = true
+                       # New style mipmap
+                       if "{project_root}/android/res/mipmap-{res}/ic_launcher_round.png".file_exists then
+                               has_round = true
+                       end
+                       if "{project_root}/android/res/mipmap-{res}/ic_launcher.png".file_exists then
+                               icon_name = "@mipmap/ic_launcher"
+                               break
+                       end
+                       if "{project_root}/android/res/mipmap-{res}/ic_launcher.xml".file_exists then
+                               icon_name = "@mipmap/ic_launcher"
                                break
                        end
                end
+               if icon_name == null then
+                       # Old style drawable-hdpi/icon.png
+                       for res in resolutions do
+                               var path = project_root / "android/res/drawable-{res}/icon.png"
+                               if path.file_exists then
+                                       icon_name = "@drawable/icon"
+                                       break
+                               end
+                       end
+               end
 
                var icon_declaration
-               if icon_available then
-                       icon_declaration = "android:icon=\"@drawable/icon\""
+               if icon_name != null then
+                       icon_declaration = "android:icon=\"{icon_name}\""
+                       if app_target_api >= 25 and has_round then
+                               icon_declaration += "\n\t\tandroid:roundIcon=\"@mipmap/ic_launcher_round\""
+                       end
                else icon_declaration = ""
 
-               # Also copy over the java files
-               dir = "{android_project_root}/src/"
+               # TODO android:roundIcon
+
+               # Copy the Java sources files
+               var java_dir = android_app_main / "java/"
+               java_dir.mkdir
                for mmodule in compiler.mainmodule.in_importation.greaters do
                        var extra_java_files = mmodule.extra_java_files
                        if extra_java_files != null then for file in extra_java_files do
-                               var path = file.filename
-                               path.file_copy_to(dir/path.basename(""))
-                       end
-               end
-
-               ## Generate delegating makefile
-               dir = "{android_project_root}/jni/"
-               """
-include $(call all-subdir-makefiles)
-               """.write_to_file("{dir}/Android.mk")
-
-               # Gather ldflags for Android
-               var ldflags = new Array[String]
-               var platform_name = "android"
-               for mmodule in compiler.mainmodule.in_importation.greaters do
-                       if mmodule.ldflags.keys.has(platform_name) then
-                               ldflags.add_all mmodule.ldflags[platform_name]
+                               var path = file.src_path
+                               var dir = file.filename.dirname
+                               (java_dir/dir).mkdir
+                               path.file_copy_to(java_dir/file.filename)
                        end
                end
 
-               ### generate makefile into "{compile_dir}/Android.mk"
-               dir = compile_dir
-               """
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS   := -D ANDROID -D WITH_LIBGC
-LOCAL_MODULE    := main
-LOCAL_SRC_FILES := \\
-{{{cfiles.join(" \\\n")}}}
-LOCAL_LDLIBS    := {{{ldflags.join(" ")}}} libgc.a
-LOCAL_STATIC_LIBRARIES := android_native_app_glue png
-
-include $(BUILD_SHARED_LIBRARY)
-
-$(call import-module,android/native_app_glue)
-               """.write_to_file("{dir}/Android.mk")
+               # ---
+               # /app/src/main/AndroidManifest.xml
 
-               ### generate AndroidManifest.xml
-               dir = android_project_root
-               """<?xml version="1.0" encoding="utf-8"?>
-<!-- BEGIN_INCLUDE(manifest) -->
+               var manifest_file = new FileWriter.open(android_app_main / "AndroidManifest.xml")
+               manifest_file.write """
+<?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="{{{app_package}}}"
-        android:versionCode="{{{project.version_code}}}"
-        android:versionName="{{{app_version}}}">
-
-    <!-- This is the platform API where NativeActivity was introduced. -->
-    <uses-sdk
-        android:minSdkVersion="{{{app_min_api}}}"
-        android:targetSdkVersion="{{{app_target_api}}}"
-        {{{app_max_api}}} />
+        package="{{{app_package}}}">
 
     <application
-               android:label="@string/app_name"
                android:hasCode="true"
-               android:debuggable="{{{not release}}}"
-               {{{icon_declaration}}}
-               android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                android:label="@string/app_name"
+               android:allowBackup="true"
+               android:label="@string/app_name"
+               {{{icon_declaration}}}>
+"""
+
+               for activity in project.activities do
+                       manifest_file.write """
+        <activity android:name="{{{activity}}}"
                 {{{project.manifest_activity_attributes.join("\n")}}}
                 {{{icon_declaration}}}>
-            <!-- Tell NativeActivity the name of our .so -->
-            <meta-data android:name=\"android.app.lib_name\"
-                    android:value=\"main\" />
+
+            <meta-data android:name="android.app.lib_name" android:value="nit_app" />
+
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+"""
+               end
 
+               manifest_file.write """
 {{{project.manifest_application_lines.join("\n")}}}
 
     </application>
@@ -217,110 +466,30 @@ $(call import-module,android/native_app_glue)
 {{{project.manifest_lines.join("\n")}}}
 
 </manifest>
-<!-- END_INCLUDE(manifest) -->
-               """.write_to_file("{dir}/AndroidManifest.xml")
-
-               ### Link to png sources
-               # libpng is not available on Android NDK
-               # FIXME make obtionnal when we have alternatives to mnit
-               var nit_dir = toolcontext.nit_dir
-               var share_dir =  nit_dir/"share/"
-               if not share_dir.file_exists then
-                       print "Android project error: Nit share directory not found, please use the environment variable NIT_DIR"
-                       exit 1
-               end
-               share_dir = share_dir.realpath
-               var target_png_dir = "{android_project_root}/jni/png"
-               if not target_png_dir.file_exists then
-                       toolcontext.exec_and_check(["ln", "-s", "{share_dir}/png/", target_png_dir], "Android project error")
-               end
-
-               # Ensure that android-setup-libgc.sh has been executed
-               if not "{share_dir}/libgc/lib".file_exists then
-                       toolcontext.exec_and_check(["{share_dir}/libgc/android-setup-libgc.sh"], "Android project error")
-               end
-
-               # Copy GC files
-               toolcontext.exec_and_check(["cp", "{share_dir}/libgc/lib/libgc.a", "{android_project_root}/libgc.a"], "Android project error")
-               toolcontext.exec_and_check(["ln", "-s", "{share_dir}/libgc/include/gc/", "{android_project_root}/jni/nit_compile/gc"], "Android project error")
-
-               ### Link to assets (for mnit and others)
-               # This will be accessed from `android_project_root`
-               var assets_dir
-               if compiler.mainmodule.location.file != null then
-                       # it is a real file, use "{file}/../assets"
-                       assets_dir = "{compiler.mainmodule.location.file.filename.dirname}/../assets"
-               else
-                       # probably used -m, use "."
-                       assets_dir = "assets"
-               end
-               if assets_dir.file_exists then
-                       assets_dir = assets_dir.realpath
-                       var target_assets_dir = "{android_project_root}/assets"
-                       if not target_assets_dir.file_exists then
-                               toolcontext.exec_and_check(["ln", "-s", assets_dir, target_assets_dir], "Android project error")
-                       end
-               end
-
-               ### Copy resources and libs where expected by the SDK
-               var project_root
-               if compiler.mainmodule.location.file != null then
-                       # it is a real file, use "{file}/../res"
-                       project_root = "{compiler.mainmodule.location.file.filename.dirname}/.."
-               else
-                       # probably used -m, use "."
-                       project_root = "."
-               end
-
-               # Android resources folder
-               var res_dir = project_root / "res"
-               if res_dir.file_exists then
-                       # copy the res folder to .nit_compile
-                       res_dir = res_dir.realpath
-                       toolcontext.exec_and_check(["cp", "-R", res_dir, android_project_root], "Android project error")
-               end
-
-               if not res_dir.file_exists or not "{res_dir}/values/strings.xml".file_exists then
-                       # Create our own custom `res/values/string.xml` with the App name
-"""<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="app_name">{{{app_name}}}</string>
-</resources>""".write_to_file "{dir}/res/values/strings.xml"
-               end
-
-               # Android libs folder
-               var libs_dir = project_root / "libs"
-               if libs_dir.file_exists then
-                       toolcontext.exec_and_check(["cp", "-r", libs_dir, android_project_root], "Android project error")
-               end
+"""
+               manifest_file.close
        end
 
-       redef fun write_makefile(compiler, compile_dir, cfiles)
+       redef fun write_makefile(compile_dir, cfiles)
        do
                # Do nothing, already done in `write_files`
        end
 
-       redef fun compile_c_code(compiler, compile_dir)
+       redef fun compile_c_code(compile_dir)
        do
                var android_project_root = android_project_root.as(not null)
-               var short_project_name = compiler.mainmodule.name.replace("-", "_")
                var release = toolcontext.opt_release.value
 
-               # Compile C code (and thus Nit)
-               toolcontext.exec_and_check(["ndk-build", "-s", "-j", "-C", android_project_root], "Android project error")
-
-               # Generate the apk
-               var args = ["ant", "-q", "-f", android_project_root+"/build.xml"]
-               if release then
-                       args.add "release"
-               else args.add "debug"
+               # Compile C and Java code into an APK file
+               var verb = if release then "assembleRelease" else "assembleDebug"
+               var args = [gradlew_dir/"gradlew", verb, "-p", android_project_root]
+               if toolcontext.opt_verbose.value <= 1 then args.add "-q"
                toolcontext.exec_and_check(args, "Android project error")
 
-               # Move the apk to the target
+               # Move the APK to the target
                var outname = outfile(compiler.mainmodule)
-
                if release then
-                       var apk_path = "{android_project_root}/bin/{short_project_name}-release-unsigned.apk"
+                       var apk_path = "{android_project_root}/app/build/outputs/apk/release/app-release-unsigned.apk"
 
                        # Sign APK
                        var keystore_path= "KEYSTORE".environ
@@ -328,10 +497,16 @@ $(call import-module,android/native_app_glue)
                        var tsa_server= "TSA_SERVER".environ
 
                        if key_alias.is_empty then
-                               toolcontext.fatal_error(null,
-                                       "Fatal Error: the environment variable `KEY_ALIAS` must be set to use the `--release` option on Android projects.")
+                               toolcontext.warning(null, "key-alias",
+                                       "Warning: the environment variable `KEY_ALIAS` is not set, the APK file will not be signed.")
+
+                               # Just move the unsigned APK to outname
+                               args = ["mv", apk_path, outname]
+                               toolcontext.exec_and_check(args, "Android project error")
+                               return
                        end
 
+                       # We have a key_alias, try to sign the APK
                        args = ["jarsigner", "-sigalg", "MD5withRSA", "-digestalg", "SHA1", apk_path, key_alias]
 
                        ## Use a custom keystore
@@ -350,7 +525,7 @@ $(call import-module,android/native_app_glue)
                        toolcontext.exec_and_check(args, "Android project error")
                else
                        # Move to the expected output path
-                       args = ["mv", "{android_project_root}/bin/{short_project_name}-debug.apk", outname]
+                       args = ["mv", "{android_project_root}/app/build/outputs/apk/debug/app-debug.apk", outname]
                        toolcontext.exec_and_check(args, "Android project error")
                end
        end
@@ -359,9 +534,9 @@ end
 redef class JavaClassTemplate
        redef fun write_to_files(compdir)
        do
-               var jni_path = "jni/nit_compile/"
+               var jni_path = "cpp/"
                if compdir.has_suffix(jni_path) then
-                       var path = "{compdir.substring(0, compdir.length-jni_path.length)}/src/"
+                       var path = "{compdir.substring(0, compdir.length-jni_path.length)}/java/"
                        return super(path)
                else return super
        end