powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Это как?
9 сообщений из 9, страница 1 из 1
Это как?
    #39768481
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Периодически падает Xpath.evaluate если звать параллельно. На винде где то 1%, на линуксе 90%. Нашел баг:
https://bugs.openjdk.java.net/browse/JDK-8179941
Решил раскопать, и вот...
...
Рейтинг: 0 / 0
Это как?
    #39768505
Фотография Герой дня
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no56892,

fParseInProgress - статическая? если статическая, то парсер однопоточный. Иначе непонятно, как может падать.
...
Рейтинг: 0 / 0
Это как?
    #39768509
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Герой дня,

protected boolean fParseInProgress = false;

Тогда и вопроса то не было.
Однопоточный? То есть во всем приложении вообще любое выполнение Xpath надо в синхронайзд помещать?

Там по ссылке вполне резонный пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
import java.io.StringReader;

import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.xml.sax.InputSource;

public class XPathTest {

    // This field is set to true as soon as one thread encounters an exception. When this happens, both threads will terminate.
    private static volatile boolean exception;

    private static Object lock = new Object();

    public static void main(String[] args) {
        Thread thread1 = createThread();
        Thread thread2 = createThread();
        thread1.start();
        thread2.start();
        try {
            // wait at most two minutes
            thread1.join(60000);
            thread2.join(60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static Thread createThread() {
        String xml = "<test/>";
        return new Thread(new Runnable() {
            @Override
            public void run() {
                while (!exception) {
                    try {
                        XPathFactory xPathFactory;
                        // Synchronize both threads, as XPathFactory.newInstance() is not thread-safe.
                        synchronized (lock) {
                            xPathFactory = XPathFactory.newInstance();
                        }
                        xPathFactory.newXPath().compile("/test").evaluate(new InputSource(new StringReader(xml)));
                    } catch (XPathExpressionException e) {
                        e.printStackTrace();
                        exception = true;
                    }
                }
            }
        });

    }
}
...
Рейтинг: 0 / 0
Это как?
    #39768520
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no56892,

Вот ты чудак. Да 99% алгоритмов пр своей природе - одно поточные.

Если ты хочешь долбить экземпляр алгоритма из двух и более потоков - создай из фабрики 2 и более экземпляра нужного алгоритма.
...
Рейтинг: 0 / 0
Это как?
    #39768522
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
Не понял мысли, что за алгоритмы (а) и где они долбятся (б) из нескольких потоков?
...
Рейтинг: 0 / 0
Это как?
    #39768580
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no56892,
Такой баг даже есть https://issues.apache.org/jira/browse/XALANJ-2463?attachmentOrder=desc, но похоже на него тупо забили, 10 лет прошло.
Проблема оказалась в классе XPathExpressionImpl, там есть 3 статик ансейф поля:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
static DocumentBuilderFactory dbf = null;
    static DocumentBuilder db = null;
    static Document d = null;

и далее по тексту:

if ( dbf == null ) {
                dbf = FactoryImpl.getDOMFactory(useServicesMechanism);
                dbf.setNamespaceAware( true );
                dbf.setValidating( false );
            }
            db = dbf.newDocumentBuilder();
            Document document = db.parse( source );


На скриншоте в первом посте, собственно и парсится этим db, одним единственным, то есть флаг был тру, зашел первый поток, затем второй закончил парсить поставил флаг фалс, и тут я поймал в дебаге.
То есть это делает невозможным какое-то вменяемое использование "штатного" Xpath в принципе. Единственно, что заработает ок это:
Код: java
1.
2.
3.
synchronized (GLOBAL_LOCK) {
     XPathFactory.newInstance().newXPath().compile("/test").evaluate(new InputSource(new StringReader(xml)));
}


И это вообще для каждого, даже не связанного между собой выражения ВО ВСЕМ ПРИЛОЖЕНИИ (в пределах класслоудера правда, но в большинстве случаев он и есть один на все приложение), и никакой строчки из синхронайзд отсюда нельзя выкинуть, ни фабрику закешировать, не уж тем более скомпилированное выражение xpath, ничего!

Здорово, правда?
...
Рейтинг: 0 / 0
Это как?
    #39768588
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no56892,
Нашел там еще метод есть один, может авторы посчитали что компилировать выражение это дешево? Надо проверить будет, вообщем вот так тоже прокатит:
Код: java
1.
2.
3.
4.
5.
XPath xPath = null;
     synchronized (GLOBAL_LOCK) {
         xPath = XPathFactory.newInstance().newXPath();
     }
xPath.evaluate("/test", new InputSource(new StringReader(xml)));


И может даже можно newXPath вынести, надо будет детально посмотреть что он там передает при создании. Но все равно я оч сильно удивлен, что в джаве любое скопилированное икспас выражение нужно вставлять в глобал лок.
...
Рейтинг: 0 / 0
Это как?
    #39768595
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм... Мдя.

Интересно узнать следуюшую инфу. Баг создан на восьмерку и девятку. Сейчас транковая HEAD версия это 11.
Воспроизводится ли дефект в ней?

По каментам. Какой-то особой активности по ней нету. Приоритет выставили в "P4". (Что за хрень? Непоня...)
Fix versions - to be discussed.

Похоже никого особо не парит.

Сама библиотечка com.sun.org.apache.xerces где лежат эти исходники производит хреновенькое впречатление.
По коду Sonar ругается много.

Есть предположение что fParseInProgress это след некой нативной оптимизации где что-то лежало не в Java
а в сях и потом так и осталось.

По исходникам на OpenJDK по ветке Xerces никаких за год не было изменений чтоб фиксили именно механизмы
XPath. Если судить по текстовым каментам Git.
...
Рейтинг: 0 / 0
Это как?
    #39769110
lleming
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно попробовать сделать threadlocal и для каждого потока отдельный экземпляр (через classloader сделать "независимые") парсера.

Грязно конешно но как воркараунд если уперлись во чтото, то можно, ну или воспользоваться другим парсером
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Это как?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]