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

fParseInProgress - статическая? если статическая, то парсер однопоточный. Иначе непонятно, как может падать.
...
Рейтинг: 0 / 0
01.02.2019, 20:53
    #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
01.02.2019, 21:16
    #39768520
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Это как?
no56892,

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

Если ты хочешь долбить экземпляр алгоритма из двух и более потоков - создай из фабрики 2 и более экземпляра нужного алгоритма.
...
Рейтинг: 0 / 0
01.02.2019, 21:18
    #39768522
no56892
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Это как?
mayton,
Не понял мысли, что за алгоритмы (а) и где они долбятся (б) из нескольких потоков?
...
Рейтинг: 0 / 0
02.02.2019, 00:38
    #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
02.02.2019, 01:07
    #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
02.02.2019, 02:27
    #39768595
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Это как?
Хм... Мдя.

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

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

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

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

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

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

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


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