Is there any way to run a java program (.jar) from a C or C++ program?

Asked

Viewed 965 times

12

I wonder if there’s a way I can write a program .jar, and write a C/C++ program that called the JVM to run the file .jar. Is it possible? If so, can you give me an example of code or an instruction on how to do this?

2 answers

10

You can use the command line (system()):

 java -jar "arquivo.jar"

Depending on what you want to do you can use JNI. It’s very complicated.

  • 2

    Depending on the case has the JNA also.

  • Thank you. I have already found the answer in a similar question.

9


The most standard solution would be using the function system() of the standard library stdlib.h.

HOWEVER, from the point of view of systems *nix, the use of system() should be avoided:

1 - The call of the function system() executes the command interpreter (shell) which makes it much slower than the call of a fork() followed by a exec();

2 - It is a potential safety risk if you pass as parameter an unreliable source string;

3 - It cannot be used asynchronously, that is, the system is locked awaiting the return of the child process;

4 - The duo fork() and exec() gives us much greater control before and between their calls.

The following program exemplifies the execution of a .jar using the calls of fork(), exec() and waitpid() in a system Linux.

Note that the process child, before making the call of exec(), prepares the environment by redirecting the output streams (STDERR and STDOUT) for two output files: stderr.txt and stdout.txt.

The flow of the parent process is blocked on purpose with the waitpid(), but could be "working" on another task:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#define MAX_CMD_TAM  (1024)

int main( int argc, char * argv[] )
{
    char cmd[ MAX_CMD_TAM + 1 ] = {0};

    /* Verifica se o nome de arquivo .jar foi passado como parametro na linha de comando */
    if( argc != 2 )
    {
        printf("Erro de sintaxe: %s [ARQUIVO_JAR]\n", argv[0] );
        return 1;
    }

    /* Processo pai cria uma copia de si mesmo (cria um processo filho) */
    pid_t child = fork();

    /* Monta a linha de comando que sera executada */
    snprintf( cmd, MAX_CMD_TAM, "java -jar %s", argv[1] );

    if( child == 0 ) /* Fluxo do processo filho */
    {
        /* Abre/Cria arquivos para substituirem as saidss padroes: STDOUT e STDERR */
        int fdout = open( "stdout.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR );
        int fderr = open( "stderr.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR );

        /* Redireciona o STDOUT e STDERR para os arquivos correspondentes */
        dup2( fdout, STDOUT_FILENO );
        dup2( fderr, STDERR_FILENO );

        /* Depois de duplicados, os descritores dos arquivos nao sao mais necessarios */
        close(fdout);
        close(fderr);

        /* Executa comando */
        execlp( cmd, NULL );
    }
    else if( child > 0 ) /* Fluxo do processo pai */
    {
        /* Processo pai aguarda a execucao do processo filho */
        printf( "Executando Comando: \"%s\"\n", cmd );

        printf( "Aguardando a execucao do processo filho...\n");
        waitpid(child);

        printf("Sucesso!\n");
    }
    else
    {
        printf("fork() falhou!\n");
        return 1;
    }

    return 0;
}

/* fim-de-arquivo */

I hope I’ve helped!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.