DEV Community

Query Filter
Query Filter

Posted on

bridge10

plugins {
    id 'java'
    id 'com.github.johnrengelman.shadow' version '7.0.0'
}

// Configuration from your existing setup
def agentSrcDir = file("$buildDir/generated-src/agent")
def attacherSrcDir = file("$buildDir/generated-src/attacher")

def profilerConfig = [
    targetClassesFile: file("${projectDir}/profiler_targets.txt"),
    intervalSeconds  : 60,
    outputDir        : file("$buildDir/profiler-results")
]

// Formatting helper for consistent arguments
def getAgentArgs = { 
    return "${profilerConfig.targetClassesFile.absolutePath};${profilerConfig.intervalSeconds};${profilerConfig.outputDir.absolutePath}"
}

// --- 1. YOUR EXISTING TASKS (Fixed OCR) ---
task generateAgentSourceTask {
    doLast {
        agentSrcDir.mkdirs()
        file("${agentSrcDir}/comet/agent/ProfilerAgent.java").text = """
package comet.agent;
import java.lang.instrument.Instrumentation;
public class ProfilerAgent {
    public static void premain(String args, Instrumentation inst) {
        System.out.println("[Agent] Static attach. Args: " + args);
    }
    public static void agentmain(String args, Instrumentation inst) {
        System.out.println("[Agent] Dynamic attach. Args: " + args);
        premain(args, inst);
    }
}"""
    }
}

task compileAgent(type: JavaCompile, dependsOn: generateAgentSourceTask) {
    source = fileTree(agentSrcDir)
    classpath = sourceSets.main.runtimeClasspath
    destinationDirectory = file("$buildDir/agent-classes")
}

task buildAgent(type: Jar, dependsOn: compileAgent) {
    archiveBaseName = 'profiler-agent'
    from compileAgent.destinationDirectory
    manifest {
        attributes(
            'Premain-Class': 'comet.agent.ProfilerAgent',
            'Agent-Class': 'comet.agent.ProfilerAgent', // Added for dynamic support
            'Can-Redefine-Classes': 'true',
            'Can-Retransform-Classes': 'true'
        )
    }
}

// --- 2. NEW ATTACHER TASKS (Reusing Agent) ---

task generateAttacherSource {
    doLast {
        attacherSrcDir.mkdirs()
        file("${attacherSrcDir}/comet/agent/UniversalAttacher.java").text = """
package comet.agent;
import net.bytebuddy.agent.ByteBuddyAgent;
import java.io.File;

public class UniversalAttacher {
    public static void main(String[] args) {
        String pid = args.length > 0 ? args[0] : null;
        String options = args.length > 1 ? args[1] : "${getAgentArgs()}";

        if (pid == null) {
            System.err.println("Usage: java -jar profiler-all.jar <PID> [ARGS]");
            System.exit(1);
        }

        try {
            // Find the JAR file we are currently running
            File self = new File(UniversalAttacher.class.getProtectionDomain().getCodeSource().getLocation().toURI());

            // Validate target file existence
            String targetsPath = options.split(";")[0];
            if (!new File(targetsPath).exists()) {
                System.err.println("ERROR: Target file missing: " + targetsPath);
                System.exit(1);
            }

            System.out.println("Attaching to PID: " + pid);
            ByteBuddyAgent.attach(self, pid, options);
            System.out.println("Attachment Successful.");
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}"""
    }
}

task compileAttacher(type: JavaCompile, dependsOn: generateAttacherSource) {
    source = fileTree(attacherSrcDir)
    classpath = sourceSets.main.runtimeClasspath
    destinationDirectory = file("$buildDir/attacher-classes")
}

// This task builds the "All-in-One" suite by merging the Agent and the Attacher
shadowJar {
    group = "Distribution"
    description = "Builds the universal attacher + agent suite"

    archiveBaseName.set('profiler-all-in-one')

    // REUSE: Pull classes from your existing buildAgent task and the new attacher
    from compileAgent.destinationDirectory
    from compileAttacher.destinationDirectory

    configurations = [project.configurations.runtimeClasspath]

    relocate 'net.bytebuddy', 'comet.shaded.bytebuddy'

    manifest {
        attributes(
            'Main-Class': 'comet.agent.UniversalAttacher', // Launcher
            'Premain-Class': 'comet.agent.ProfilerAgent',   // Static Agent
            'Agent-Class': 'comet.agent.ProfilerAgent',     // Dynamic Agent
            'Can-Retransform-Classes': 'true'
        )
    }
}

// --- 3. SCRIPT GENERATION ---

task generateLaunchers {
    doLast {
        def libsDir = file("$buildDir/libs")
        def jarName = shadowJar.archiveFileName.get()

        file("$libsDir/attach.sh").text = """#!/bin/bash
PID=\$1
ARGS=\${2:-"${getAgentArgs()}"}
if [ -z "\$PID" ]; then jps -l; exit 1; fi
JAVA_CMD="java"
[ -f "/opt/.java..8--/jdk/bin/java" ] && JAVA_CMD="/opt/.java..8--/jdk/bin/java"
\$JAVA_CMD -jar $jarName \$PID "\$ARGS"
"""
        file("$libsDir/attach.bat").text = """@echo off
if "%~1"=="" ( jps -l & exit /b 1 )
java -jar $jarName %1 "${getAgentArgs()}"
"""
        if (!org.gradle.internal.os.OperatingSystem.current().isWindows()) {
            "chmod +x $buildDir/libs/attach.sh".execute()
        }
    }
}

shadowJar.finalizedBy generateLaunchers
Enter fullscreen mode Exit fullscreen mode

Top comments (0)