diff --git a/server/src/main/java/com/defold/extender/Extender.java b/server/src/main/java/com/defold/extender/Extender.java index a583a372..ae0a2875 100644 --- a/server/src/main/java/com/defold/extender/Extender.java +++ b/server/src/main/java/com/defold/extender/Extender.java @@ -525,6 +525,13 @@ public File buildJavaExtension(File manifest, Map manifestContex if (rJar != null) { classPath += ":" + rJar.getAbsolutePath(); } + + // Get extension supplied Jar libraries + List extJars = getJars(extDir); + for (String jarPath : extJars) { + classPath += ":" + jarPath; + } + context.put("classPath", classPath); context.put("sourcesListFile", sourcesListFile.getAbsolutePath()); String command = templateExecutor.execute(platformConfig.javacCmd, context); diff --git a/server/src/test/java/com/defold/extender/ExtenderTest.java b/server/src/test/java/com/defold/extender/ExtenderTest.java index 7fe4d5de..6b308891 100644 --- a/server/src/test/java/com/defold/extender/ExtenderTest.java +++ b/server/src/test/java/com/defold/extender/ExtenderTest.java @@ -290,7 +290,7 @@ public void testCollectLibraries() { @Test public void testCollectJars() { List result = Extender.collectFilesByPath(new File("test-data/ext/lib/armv7-android"), "(.+\\.jar)"); - assertEquals(1, result.size()); + assertEquals(2, result.size()); assertTrue(result.get(0).endsWith("test-data/ext/lib/armv7-android/Dummy.jar")); } diff --git a/server/src/test/java/com/defold/extender/IntegrationTest.java b/server/src/test/java/com/defold/extender/IntegrationTest.java index f2e2668f..321ea44f 100644 --- a/server/src/test/java/com/defold/extender/IntegrationTest.java +++ b/server/src/test/java/com/defold/extender/IntegrationTest.java @@ -393,6 +393,69 @@ public void buildAndroidCheckCompiledJava() throws IOException, ExtenderClientEx assertTrue(dexClasses.contains("Lcom/defold/Test;")); } + /* + * Test if a Java source can import classes specified in a supplied Jar file. + */ + @Test + public void buildAndroidJavaJarDependency() throws IOException, ExtenderClientException, InterruptedException { + + org.junit.Assume.assumeTrue("Defold version does not support Java compilation test.", + configuration.platform.contains("android") && + (configuration.version.version.isGreaterThan(1, 2, 103) || configuration.version.version.isVersion(0, 0, 0) ) + ); + + clearCache(); + + File cacheDir = new File("build"); + ExtenderClient extenderClient = new ExtenderClient("http://localhost:" + EXTENDER_PORT, cacheDir); + List sourceFiles = Lists.newArrayList( + new FileExtenderResource("test-data/ext/ext.manifest"), + new FileExtenderResource("test-data/ext/src/test_ext.cpp"), + new FileExtenderResource("test-data/ext/src/TestJar.java"), + new FileExtenderResource("test-data/ext/lib/armv7-android/libalib.a"), + new FileExtenderResource("test-data/ext/lib/armv7-android/JarDep.jar")); + File destination = Files.createTempFile("dmengine", ".zip").toFile(); + File log = Files.createTempFile("dmengine", ".log").toFile(); + + String platform = configuration.platform; + String sdkVersion = configuration.version.sha1; + + try { + extenderClient.build( + platform, + sdkVersion, + sourceFiles, + destination, + log + ); + } catch (ExtenderClientException e) { + System.out.println(new String(Files.readAllBytes(log.toPath()))); + throw e; + } + + assertTrue("Resulting engine should be of a size greater than zero.", destination.length() > 0); + assertEquals("Log should be of size zero if successful.", 0, log.length()); + + ZipFile zipFile = new ZipFile(destination); + ZipEntry classesDexEntry = zipFile.getEntry("classes.dex"); + assertNotEquals(null, classesDexEntry); + assertNotEquals(null, zipFile.getEntry("libdmengine.so")); + + + InputStream in = zipFile.getInputStream(classesDexEntry); + Path tmpClassesDexPath = Files.createTempFile("classes", "dex"); + Files.copy(in, tmpClassesDexPath, StandardCopyOption.REPLACE_EXISTING); + + // Verify that classes.dex contains our Dummy class and our compiled Java class + DexFile dexFile = DexFileFactory.loadDexFile(tmpClassesDexPath.toFile().getAbsolutePath(), 19 ); // api level + Set dexClasses = new HashSet<>(); + for (ClassDef classDef: dexFile.getClasses()) { + dexClasses.add(classDef.getType()); + } + + assertTrue(dexClasses.contains("Lcom/defold/JarDep;")); + assertTrue(dexClasses.contains("Lcom/defold/Test;")); + } @Test public void buildAndroidRJar() throws IOException, ExtenderClientException, InterruptedException { diff --git a/server/test-data/ext/lib/armv7-android/JarDep.jar b/server/test-data/ext/lib/armv7-android/JarDep.jar new file mode 100644 index 00000000..fc89d60e Binary files /dev/null and b/server/test-data/ext/lib/armv7-android/JarDep.jar differ diff --git a/server/test-data/ext/src/TestJar.java b/server/test-data/ext/src/TestJar.java new file mode 100644 index 00000000..06106195 --- /dev/null +++ b/server/test-data/ext/src/TestJar.java @@ -0,0 +1,9 @@ +package com.defold; + +import com.defold.JarDep; + +class Test { + static String doStuff() { + return JarDep.DoStuff(); + } +} \ No newline at end of file