jruby e jni

Posted on February 13, 2009

1


Como fazer em ruby para buscar o processId(PID) da thread corrente ?

Em java é possível acessar de forma nativa um método em C que tem acesso a tal informação via JNI.
E se em ruby conseguimos acessar uma classe java com JRuby, podemos conseguir esse PID.

Vamos criar a primeira parte, a implementação java que via JNI consegue o processId.

Primeiro a classe java:

class GetPid {
public GetPid(){}
public native long getpid ();
static {
System.loadLibrary("getpid");
}
public static void main (String[] args) {
GetPid gp = new GetPid ();
gp.getpid();
}
}

O método getpid é native, ou seja, será um método escrito em C.

Compilamos o GetPid.java:
$ javac GetPid.java

E em seguida geramos os cabeçalhos(headers) da implementação nativa:
$ javah GetPid

O comando acima gera o seguinte código
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class GetPid */
#ifndef _Included_GetPid
#define _Included_GetPid
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: GetPid
* Method: getpid
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_GetPid_getpid
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

Esse é apenas o cabeçalho, precisamos da implementação do método em C, no arquivo GetPid.c:

#include "getPid.h"
JNIEXPORT jlong JNICALL Java_GetPid_getpid (JNIEnv * env, jobject jobj){
return getpid();
}

Agora vamos usar o gcc para compilar o arquivo, dependendo do seu sistema operacional a forma é diferente:

Linux
# gcc -shared -fpic -o libgetpid.so -I/usr/java/include -I/usr/java/include/linux getPid.c
Mac OSX
# gcc -dynamiclib -o libgetpid.jnilib -I/System/Library/Frameworks/JavaVM.framework/Headers GetPid.c -framework JavaVM

Agora falta fazer o link entre suas variáveis de ambiente e o Java:

$ LD_LIBRARY_PATH=.
$ export LD_LIBRARY_PATH

Se tudo correr bem, podemos testar a primeira parte com:

$ java GetPid

  • Buscando PID a partir da classe Ruby com JRuby
  • Até agora conseguimos o processId através de JNI. Vamos agora usar o jruby para a partir de uma classe ruby
    mostrar o PID.
    O primeiro passo é configurar o JRuby. Se você não fez isso ainda pode seguir por aqui.

    Agora vamos criar a classe JRubyGetPid.rb:
    require 'java'
    include_class 'GetPid'
    gp = GetPid.new
    puts gp.getpid

    O código é bem simples e agora temos as 3 linguagens interligadas via JNI e JRuby:
    Ruby -> Java -> C

    Para rodar e ver o resultado, execute:
    $ jruby JRubyGetPid.rb

    Posted in: c, java, jni, jruby, ruby