2
* Copyright (c) 2014 Jared González
4
* Permission is hereby granted, free of charge, to any
5
* person obtaining a copy of this software and associated
6
* documentation files (the "Software"), to deal in the
7
* Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish,
9
* distribute, sublicense, and/or sell copies of the
10
* Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice
14
* shall be included in all copies or substantial portions of
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
18
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
20
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
21
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
* File: com_jarego_jayatana_Agent.c
27
* Author: Jared González
36
#include "com_jarego_jayatana_Agent.h"
39
* Inicializar observadores de componentes para prevenir la integración
42
jvmtiError com_jarego_jayatana_Initialize(JavaVM *vm, int fromAgent);
45
* Validar el valor de una variable de ambiente para más opciones o
46
* variables de configuración.
48
int com_jarego_jayatana_Agent_CheckEnv(const char *envname, const char *envval, const int def);
51
* Iniciar observador de inicio de hilos para prevenir la integración
55
com_jarego_jayatana_Agent_threadStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread) {
56
// recuperar información del hilo
59
error = (*jvmti_env)->GetThreadInfo(jvmti_env, thread, &info);
60
if (error == JVMTI_ERROR_NONE) {
61
// inicializar XInitThreads para corregir defecto en OpenJDK 6 para los hilos de AWT o
63
if (strcmp(info.name, "Java2D Disposer") == 0) {
64
// inicializar hilos de X, solo para OpenJDK 6
66
if ((*jvmti_env)->GetSystemProperty(
67
jvmti_env, "java.vm.specification.version", &version) == JVMTI_ERROR_NONE) {
68
if (strcmp(version, "1.0") == 0) {
69
// TODO: Utilizando openjdk6, al actualizar el objeto
70
// splashScreen (splashScreen.update) la aplicacion muere.
71
// Existe un conflicto al utilizar XInitThread y pthread.
73
// java: pthread_mutex_lock.c:317: __pthread_mutex_lock_full: La declaración `(-(e)) != 3 || !robust' no se cumple.
76
(*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)version);
78
} else if (strcmp(info.name, "AWT-XAWT") == 0) {
79
// instala la clase para control de integración Swing
80
jclass clsInstallers = (*jni_env)->FindClass(
81
jni_env, "com/jarego/jayatana/FeatureManager");
82
if (clsInstallers != NULL) {
83
jmethodID midInstallForSwing = (*jni_env)->GetStaticMethodID(
84
jni_env, clsInstallers, "deployForSwing", "()V");
85
(*jni_env)->CallStaticVoidMethod(jni_env, clsInstallers, midInstallForSwing);
86
(*jni_env)->DeleteLocalRef(jni_env, clsInstallers);
88
// una vez inicializada la prueba
89
(*jvmti_env)->SetEventNotificationMode(jvmti_env,
90
JVMTI_DISABLE, JVMTI_EVENT_THREAD_START, (jthread)NULL);
96
* Cargar agente para integración con Ubuntu/Linux
98
JNIEXPORT jint JNICALL
99
Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
100
return com_jarego_jayatana_Initialize(vm, 1);
104
* Carga libreria nativa desde agente Java para integración
107
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
108
com_jarego_jayatana_Initialize(vm, 0);
109
return JNI_VERSION_1_6;
113
* Inicializar observadores de componentes para prevenir la integración
116
jvmtiError com_jarego_jayatana_Initialize(JavaVM *vm, int fromAgent) {
117
// en caso de no exista una referencia a jayatana
118
if (getenv("JAYATANA_CLASSPATH") == NULL &&
119
access("/usr/share/java/jayatana.jar", R_OK) != 0)
120
return JVMTI_ERROR_NONE;
122
// la librería si existe iniciar procedo de validación de integración
123
if (com_jarego_jayatana_Agent_CheckEnv("XDG_CURRENT_DESKTOP", "Unity", False) ?
124
com_jarego_jayatana_Agent_CheckEnv("JAYATANA_FORCE", "true", True) &&
125
com_jarego_jayatana_Agent_CheckEnv("JAYATANA", "1", True) :
126
com_jarego_jayatana_Agent_CheckEnv("JAYATANA_FORCE", "true", False) ||
127
com_jarego_jayatana_Agent_CheckEnv("JAYATANA", "1", False)) {
129
// inicializar entorno
131
(*vm)->GetEnv(vm, (void**) &jvmti_env, JVMTI_VERSION);
135
if ((*jvmti_env)->GetSystemProperty(
136
jvmti_env, "java.vm.version", &version) == JVMTI_ERROR_NONE) {
138
// ignorar para versiones 1.4 y 1.5
139
if (strncmp(version, "1.4", 3) != 0 && strncmp(version, "1.5", 3) != 0) {
141
// activar capacidades
142
jvmtiCapabilities capabilities;
143
memset(&capabilities, 0, sizeof(jvmtiCapabilities));
144
//capabilities.can_generate_method_exit_events = 1;
145
(*jvmti_env)->AddCapabilities(jvmti_env, &capabilities);
147
// registrar funciones de eventos
148
jvmtiEventCallbacks callbacks;
149
memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
150
//callbacks.MethodExit = &com_jarego_jayatana_Agent_MethodExit;
151
callbacks.ThreadStart = &com_jarego_jayatana_Agent_threadStart;
152
(*jvmti_env)->SetEventCallbacks(jvmti_env,
153
&callbacks, (jint)sizeof(jvmtiEventCallbacks));
155
// habilitar gestor de eventos
156
(*jvmti_env)->SetEventNotificationMode(jvmti_env,
157
JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, (jthread)NULL);
158
//(*jvmti_env)->SetEventNotificationMode(jvmti_env,
159
// JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, (jthread)NULL);
161
// cargar ruta de clases jayatana
162
if (getenv("JAYATANA_CLASSPATH") != NULL) {// opción para desarrollo
163
(*jvmti_env)->AddToSystemClassLoaderSearch(
164
jvmti_env, getenv("JAYATANA_CLASSPATH"));
165
fprintf(stderr, "JAYATANA_CLASSPATH=%s\n", getenv("JAYATANA_CLASSPATH"));
167
(*jvmti_env)->AddToSystemClassLoaderSearch(
168
jvmti_env, "/usr/share/java/jayatana.jar");
172
// liberar cadena de versión
173
(*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)version);
176
return JVMTI_ERROR_NONE;
180
* Validar el valor de una variable de ambiente para más opciones o
181
* variables de configuración.
183
int com_jarego_jayatana_Agent_CheckEnv(const char *envname, const char *envval, const int def) {
184
if (getenv(envname) == NULL) return def;
185
else if (strcmp(getenv(envname), envval) == 0) return True;