Skip to content

Commit

Permalink
[fix] 添加jar解析
Browse files Browse the repository at this point in the history
  • Loading branch information
longshihan1 committed Mar 17, 2021
1 parent 87c421c commit 66c3964
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 65 deletions.
20 changes: 20 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

167 changes: 110 additions & 57 deletions LPlugin/src/main/kotlin/com/longshihan/lplugin/LTransform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import org.gradle.api.Project
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassReader.EXPAND_FRAMES
import org.objectweb.asm.ClassWriter
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.*
import java.util.*
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry

/**
* Created by longhe on 2020-07-16.
Expand All @@ -44,9 +44,9 @@ open class LTransform(val project: Project) : Transform() {

override fun transform(transformInvocation: TransformInvocation?) {
super.transform(transformInvocation)
if (!Config.enable){
if (!Config.enable) {
println("时间插桩插件关闭")
}else{
} else {
println("时间插桩插件开启")
}
try {
Expand All @@ -66,63 +66,116 @@ open class LTransform(val project: Project) : Transform() {
val outputProvider = transformInvocation?.outputProvider
inputs?.stream()?.forEach { input ->
input.jarInputs.stream().forEach { jarInput ->
val dest = outputProvider?.getContentLocation(
jarInput.file.absolutePath,
jarInput.contentTypes, jarInput.scopes, Format.JAR
)
//将修改过的字节码copy到dest,就可以实现编译期间干预字节码的目的了
FileUtils.copyFile(jarInput.file, dest)
traceJarFiles(jarInput, outputProvider)
}
input.directoryInputs.stream().forEach { directoryInput ->
val fileCPath=directoryInput.file.absolutePath
if (directoryInput.file.isDirectory) {
if (directoryInput.file.name != "META-INF") {
directoryInput.file.walk().forEach { file ->
val name = file.name
val dpath=file.absolutePath
val currentPath=dpath.replace(fileCPath,"")
.replace("/",".")
.replaceFirst(".","")
println("---------$dpath")
var isReplce=false
for (configStr in LConfig.excludes){
if (currentPath.startsWith(configStr)){
isReplce=true
break
}
}
if (!isReplce &&name.endsWith(".class") && !name.startsWith("R\$")
&& "R.class" != name && "BuildConfig.class" != name) {
try {
println("$currentPath:is changeing ,,,,")
val cr = ClassReader(file.readBytes())
val cw = ClassWriter(cr,ClassWriter.COMPUTE_MAXS)
val cv = TestMethodClassAdapter(currentPath,cw)
cr.accept(cv, EXPAND_FRAMES)
val code = cw.toByteArray()
val fos =
FileOutputStream(file.parentFile.absolutePath + File.separator + name)
fos.write(code)
fos.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
val dest = outputProvider?.getContentLocation(
directoryInput.name,
directoryInput.contentTypes,
directoryInput.scopes,
Format.DIRECTORY
)
println("----directory is location is ${dest?.absolutePath}")
FileUtils.copyDirectory(directoryInput.file, dest)
}
traceFiles(directoryInput, outputProvider)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}

fun traceFiles(directoryInput: DirectoryInput, outputProvider: TransformOutputProvider?) {
val fileCPath = directoryInput.file.absolutePath
directoryInput.file.walk().forEach { file ->
val name = file.name
val dpath = file.absolutePath
var currentPath = dpath.replace(fileCPath + File.separator, "")
println("ER:$currentPath")
currentPath = transformPath(currentPath, "\\")
if (checkPath(currentPath)&&file.isFile) {
try {
println("$currentPath:is changeing ,,,,")
val fileInputStream = FileInputStream(file)
val code = tranformBtye(fileInputStream, currentPath)
val fos = FileOutputStream(
file.parentFile.absolutePath + File.separator + name
)
fos.write(code)
fos.close()
} catch (e: Exception) {
e.printStackTrace()
}
}

}
val dest = outputProvider?.getContentLocation(
directoryInput.name,
directoryInput.contentTypes,
directoryInput.scopes,
Format.DIRECTORY
)
println("----directory is location is ${dest?.absolutePath}")
FileUtils.copyDirectory(directoryInput.file, dest)
}

fun traceJarFiles(jarInput: JarInput, outputProvider: TransformOutputProvider?) {
if (jarInput.file.absolutePath.endsWith(".jar")) {
var jarName = jarInput.name
val md5Name = DigestUtils.md5Hex(jarInput.file.absolutePath)
if (jarName.endsWith(".jar")) {
jarName = jarName.substring(0, jarName.length - 4)
}
val jarFile = JarFile(jarInput.file)
val enumeration = jarFile.entries()
val tempFile = File(jarInput.file.parent + File.separator + "classes_temp.jar")
if (tempFile.exists()) {
tempFile.delete()
}
val jarOutputStream = JarOutputStream(FileOutputStream(tempFile))
while (enumeration.hasMoreElements()) {
val jarEntry = enumeration.nextElement()
var entryName = jarEntry.name
val zipEntry = ZipEntry(entryName)
val inputStream = jarFile.getInputStream(jarEntry)
println("-=--=-===---$entryName")
entryName = transformPath(entryName, "/")
if (checkPath(entryName)) {//匹配class文件名
println("$entryName:os changeing ,,,,")
jarOutputStream.putNextEntry(zipEntry)
jarOutputStream.write(tranformBtye(inputStream, entryName))
} else {
jarOutputStream.putNextEntry(zipEntry)
jarOutputStream.write(inputStream.readBytes())
}
jarOutputStream.closeEntry()
}
jarOutputStream.close()
jarFile.close()
//处理完输出给下一任务作为输入
val dest = outputProvider?.getContentLocation(
jarName + md5Name,
jarInput.contentTypes, jarInput.scopes, Format.JAR
)
FileUtils.copyFile(tempFile, dest)
tempFile.delete()
}
}

fun tranformBtye(inputStream: InputStream, currentPath: String): ByteArray {
val cr = ClassReader(inputStream)
val cw = ClassWriter(cr, ClassWriter.COMPUTE_MAXS)
val cv = TestMethodClassAdapter(currentPath, cw)
cr.accept(cv, EXPAND_FRAMES)
return cw.toByteArray()
}

fun checkPath(path: String): Boolean {
if (path.endsWith(".class") && !path.contains("R$")
&& !path.endsWith("R.class") && !path.endsWith("BuildConfig.class")
&& !path.contains("META-INF")
) {
return true
}
return false
}

fun transformPath(path: String, sequter: String): String {
val currentPath = path.replace(sequter, ".")
println(currentPath)
return currentPath
}

}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
#org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
Expand Down
Binary file modified repo/com/longshihan/Lplugin/LPlugin/1.0.10/LPlugin-1.0.10.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ed0829f7d11d79b6f98e27f5bf6ddb59
1b15ccfd4a52b1c237a907939b05092a
Original file line number Diff line number Diff line change
@@ -1 +1 @@
eb264739330401b2364714170c18b6506f4c37b2
e17e6920b0343ce129076b23a741561670081da4
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8b1418790e739e08e854b5f5884c11bf
70935a481531b8fd248980cb82e96dd4
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b140a191b05a5bbf70f1b378c835e06a2622609b
6399ef7b62b8f4f4b359e21cf6973d76f478c1d6
2 changes: 1 addition & 1 deletion repo/com/longshihan/Lplugin/LPlugin/maven-metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
<version>1.0.9</version>
<version>1.0.10</version>
</versions>
<lastUpdated>20200821073710</lastUpdated>
<lastUpdated>20210317144915</lastUpdated>
</versioning>
</metadata>
2 changes: 1 addition & 1 deletion repo/com/longshihan/Lplugin/LPlugin/maven-metadata.xml.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f095690233b9095ae250688aa6267214
fc7dc3fe4dd70b43058cd559833bdb8d
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8e372ce1338c45aa80638f06915cec13a13069fa
831be0ce3382bb0ab4d02ea1baa1ace248141b18

0 comments on commit 66c3964

Please sign in to comment.