Search code examples
rustaeron

How can I embed the Aeron driver JAR in a Rust program and start it later?


I have a Rust program that uses Aeron through the aeron-rs crate.

Every time I want to run my program, I need to manually start the driver first. In fact, the crate explicitly states that it works simply as a wrapper around the running driver.

I would like that the driver launches upon starting my program.

I know that Aeron provides an embedded driver, but I'm clueless about how to possibly integrate it.

So far, I've put the embedded driver JAR in my src folder

my-project/
   src/
      aeron-all-1.32.0-SNAPSHOT.jar

I used the include_bytes! macro to try to include the JAR in the build

fn main() {
    include_bytes!("aeron-all-1.32.0-SNAPSHOT.jar");
}

I don't see the jar in the build folder.

Then, the following code should run the driver upon startup:

if cfg!(target_os = "windows") {
    Command::new("cmd")
        .args(&[
            "/C",
            "%JAVA_HOME%\\bin\\java \
                        -cp aeron-all-1.32.0-SNAPSHOT.jar \
                        %JVM_OPTS% io.aeron.driver.MediaDriver %*",
        ])
        .output()
        .expect("Failed to execute external process.")
} else {
    Command::new("sh")
        .arg("-c")
        .arg(
            "${JAVA_HOME}/bin/java \
                -cp aeron-all-1.32.0-SNAPSHOT.jar \
                ${JVM_OPTS} io.aeron.driver.MediaDriver \"$@\"",
        )
        .output()
        .expect("Failed to execute external process.")
};

Is this the right way to run the jar file?


Solution

  • I had to extract the bytes into a temp JAR file and I am able to run such JAR

    fn main() -> std::io::Result<()> {
        let driver_path = extract_driver();
    
        if cfg!(target_os = "windows") {
            let mut command = String::from("%JAVA_HOME%\\bin\\java -cp ");
            command.push_str(driver_path.as_str());
            command.push_str("%JVM_OPTS% io.aeron.driver.MediaDriver %*");
            Command::new("cmd")
                .args(&["/C", command.as_str()])
                .spawn()
                .expect("Error spawning Aeron driver process")
        } else {
            let mut command = String::from("${JAVA_HOME}/bin/java -cp ");
            command.push_str(driver_path.as_str());
            command.push_str("${JVM_OPTS} io.aeron.driver.MediaDriver \"$@\"");
            Command::new("sh")
                .arg("-c")
                .arg(command.as_str())
                .spawn()
                .expect("Error spawning Aeron driver process")
        };
    }
    
    fn extract_driver() -> String {
        let bytes = include_bytes!("aeron-all-1.32.0-SNAPSHOT.jar");
        let mut driver_path = temp_dir();
        driver_path.push("aeron-driver.jar");
        let mut file = File::create(driver_path.to_owned()).expect("Error extracting Aeron driver jar");
        file.write_all(bytes).unwrap();
        String::from(driver_path.to_str().unwrap())
    }