Skip to content

Commit

Permalink
Replace dx with d8
Browse files Browse the repository at this point in the history
d8 desugaring of Java 8 / Java 11 features seems to work without any --library arguments
despite d8's warnings. The resulting smali code no longer contains 'invoke-custom' statements.
Example: String#isBlank (Java 11) is replaced by a $$ExternalSyntheticBackport class.
  • Loading branch information
ollide committed May 1, 2021
1 parent 8cb83ac commit 698c3f7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
Binary file added lib/d8-31.0.0-rc3.jar
Binary file not shown.
45 changes: 45 additions & 0 deletions src/main/kotlin/org/ollide/java2smali/D8Class2DexHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.ollide.java2smali

import com.android.tools.r8.D8
import com.android.tools.r8.D8Command
import com.android.tools.r8.OutputMode
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.containers.stream
import java.nio.file.Path
import java.nio.file.Paths
import java.util.stream.Collectors

object D8Class2DexHelper {

/**
* Uses the D8 tool from the Android Build Tools to create
* a .dex version of a compiled java file (.class)
*
* @param inputClassFilePaths full paths to the compiled .class file
* @param outputDexPath this will be the dex output file's path and name
* @return `true` if dx ran successfully, otherwise `false`
*/
fun dexClassFile(inputClassFilePaths: Array<String>, outputDexPath: Path): Boolean {
val classFiles = inputClassFilePaths.stream().map { Paths.get(it) }.collect(Collectors.toList())

val command = D8Command.builder()
.setIntermediate(true)
.setMinApiLevel(30)
.addProgramFiles(classFiles)
// Add --library android.jar ?
// .addLibraryFiles(Paths.get(""))
.setOutput(outputDexPath, OutputMode.DexIndexed)
.build()

return try {
D8.run(command)
true
} catch (e: Exception) {
LOG.error("Error running D8", e)
false
}
}

private val LOG = Logger.getInstance(D8Class2DexHelper::class.java)

}
8 changes: 5 additions & 3 deletions src/main/kotlin/org/ollide/java2smali/DexCompiler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,21 @@ class DexCompiler(private val vFile: VirtualFile, private val project: Project,
fileOutputDirectory.refresh(false, false)

val fileName = vFile.nameWithoutExtension
val dexFilePath = Paths.get(fileOutputDirectory.path, fileName + DEX_EXTENSION).toString()
val dexFilePath = Paths.get(fileOutputDirectory.path)

// CLASS -> DEX
val targetFiles = getClassFiles(fileOutputDirectory, fileName)
val successfulDex = Class2DexHelper.dexClassFile(targetFiles, dexFilePath)
val successfulDex = D8Class2DexHelper.dexClassFile(targetFiles, dexFilePath)
if (!successfulDex) {
return
}

val dexFile = dexFilePath.resolve("classes$DEX_EXTENSION").toString()

// DEX -> SMALI
val outputDir = getSourceRootFile().path
WriteCommandAction.runWriteCommandAction(project) {
Dex2SmaliHelper.disassembleDexFile(dexFilePath, outputDir)
Dex2SmaliHelper.disassembleDexFile(dexFile, outputDir)

// we've created the smali file(s) in our source file's directory
// refresh directory synchronously and access children to let IDEA detect the file(s)
Expand Down

0 comments on commit 698c3f7

Please sign in to comment.