Comments 21
С выходом Java 9 — сразу до свидания!
Не надо модифицировать
java.library.path
. Про System.load() слышали?Про System.load() хорошая идея. Это как раз то, что можно было бы сделать в JDBCDriverProxyImpl. Я пробовал экспериментировать с System.load(), но ничего не получилось, из-за того, что библиотеку грузил в разных класслоадерах, а добавить JDBCDriverProxyImpl, придумал уже позже, когда уперся в DriverManager.
Надо к этой функции вернуться.
Тут есть еще такой момент, сторонняя библиотека подгружает dll не всегда, а только при определенных параметрах, я проконтролировать это не могу. Но тут можно сделать превентивную загрузку, даже если на самом деле библиотека не понадобится.
С выходом Java 9 — сразу до свидания!
Насколько мне известно, в Java 9 ломается доступ к классам в недоступных пакетах. Если пакет доступен, то setAccessible работает как раньше. Во-всяком случае, этот тест прекрасно работает в 9-ea+138:
import java.lang.reflect.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws Exception {
Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
usrPathsField.setAccessible(true);
String[] paths = (String[]) usrPathsField.get(null);
System.out.println(Arrays.toString(paths));
}
}
Кое-что в класслоадерах уже изменили в Java 9. Например, системный ClassLoader больше не наследник URLClassLoader. Но я встречал проекты, где просто кастовали системный ClassLoader, чтобы взять у него URLClassPath. И фокус с
usr_paths
из той же серии.Вот это — костыль:
System.gc();
System.runFinalization();
А если JVM оба раза откажется это делать, то что? Уж лучше лаунчер.
По факту очень многие Java-приложения делают такой маленький нативный лаунчер (как минимум, все популярные IDE — IDEA, Eclipse, NetBeans). Параметры JVM записываются в какой-нибудь конфиг или передаются как-нибудь вроде -Jblahblah
. Как минимум, это надёжнее: не всегда .jar на произвольной системе запутится как запускаемый файл. Сделать такой лаунчер совсем нетрудно, есть даже готовые генераторы этих лаунчеров.
Вот магия с ThreadLocal-ами — это самый ад здесь. Мало того что суровая завязка на реализацию. Реализация ThreadLocalMap абсолютно не потокобезопасная, потому что предполагается, что в неё никогда не залезает никто из чужого потока. Если во время вашего клинапа в другом потоке записывается какой-нибудь любой другой тредлокал, может в принципе много интересного произойти. Можно ведь и на рехэшинг напороться. Или вы не затрёте все записи, какие хотите затереть, или затрёте лишнюю запись.
Вообще правильно Лёша Шипилёв говорит. Если вы сталкиваетесь с неразрешимой проблемой в Java, правильно — написать в мейлинг-листы OpenJDK, обсудить, предложить JEP, сделать патч, дождаться выхода следующей версии Java и радоваться. А хакать джаву неправильно, работоспособность вашей программы тогда гарантировать будет невозможно. Понятно, что это слишком идеалистическая картина мира, но всё-таки стоит иметь в виду такой вариант.
Что такое JEP?
Про общение с командой OpenJDK поделитесь, пожалуйста, как это правильно делать
1. Идем и находим нужный mail list
2. Справшиваем там и/или ищем похожие проблемы в трекере
Что такое JEP?
JDK Enhancement-Proposal (JEP-2). Можно все там не читать. Это процесс для внесения новых фич и изменений в JDK.
lany для того, чтобы предложить JEP, необходимо иметь учетную запись в трекере, а значит быть OpenJDK автором.
Как выгрузить dll из Java-машины