LINUX.ORG.RU

Java 16 поломала поддержку LDAP в Spring Boot

 , , ,


0

1

Вот, не только Lombok пострадал. Всё пропало или скоро починят?

Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.springframework.ldap.core.support.LdapContextSource
	at org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration$EmbeddedLdapContextConfiguration.ldapContextSource(EmbeddedLdapAutoConfiguration.java:205) ~[spring-boot-autoconfigure-2.4.4.jar:2.4.4]
	at jdk.internal.reflect.GeneratedMethodAccessor431.invoke(Unknown Source) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.5.jar:5.3.5]
	... 127 common frames omitted

UPDATE: нашёл источник проблемы.

Exception in thread "main" java.lang.IllegalAccessError: class org.springframework.ldap.core.support.AbstractContextSource (in unnamed module @0x108c4c35) cannot access class com.sun.jndi.ldap.LdapCtxFactory (in module java.naming) because module java.naming does not export com.sun.jndi.ldap to unnamed module @0x108c4c35
	at org.springframework.ldap.core.support.AbstractContextSource.<clinit>(AbstractContextSource.java:77)

Очень похоже на то, что случилось с Lombok, но уже в JNDI LDAP:

	private static final Class<com.sun.jndi.ldap.LdapCtxFactory> DEFAULT_CONTEXT_FACTORY
            = com.sun.jndi.ldap.LdapCtxFactory.class;

UPDATE #2: В spring-ldap-core это уже исправили, исправление должно войти в следующую версию 2.3.4-RELEASE

https://github.com/spring-projects/spring-ldap/commit/0a1d3f595b670412b7fd7ab739237c57381a7fa8#diff-1b415582238c28e1c42b5ab96d862e14d8917d4e3decf1cc43f84aa45e63e7ae https://github.com/spring-projects/spring-ldap/issues/543



Последнее исправление: hummer (всего исправлений: 5)

Ответ на: комментарий от hummer

Снова тупишь. Разговор лишь о правомерности использования com.sun.* в коде.

Ты не увиливай, а расскажи свою «официальную версию» разделения

А теперь расскажи мне, какие исторические причины заставили разработчиков Java 6 использовать com.sun.net и sun.net одновременно?

Отправь им телефакс с вопросом, раз в телефонограммы не умеешь

Или почему javadoc этих абстрактных классов попал в официальную документацию?

А и в правду, как так возмутительно явадок на ораклждк попал на сайт оракл?
А теперь назови ещё пару жвм6, в которых были эти классы.
Для закрепления попробуй добавить этот класс в экслипсе с таргетом на яву 8 или ниже и посмотри что он тебе напишет

Опять поучаешь, хотя сам и по-русски-то толком разговаривать не умеешь.

Я сдаюсь, ты реально непробиваем, продолжай юзать буты, саны, лёд для пердака, просто не пиши ничего опасного для людей :-)

rukez ★★★★
()
Ответ на: комментарий от Legioner

Ты не прав. Тот же com.sun.net.httpserver всегда имел жавадок и всегда был официально доступен.

Да никто и не говорит что он был не доступен, он просто не часть языка и не обязательная часть jvm - ты можешь сделать se1.6 совместимую жвм БЕЗ этого класса и никто не в праве тебе после этого сказать что она не 1.6 совместима

Не буду утверждать, что это так для всех com.sun.*, т.е. я с ними почти не сталкивался кроме httpserver и mail.

А мейл в ждк 6/8/11 разве была?

Насколько помню, Мейл есть в ЕЕ но его нет в SE, http* вроде наоборот.
Что как-бы намекает вам в очередной раз что это жвм-зависимые вещи :-)

rukez ★★★★
()
Ответ на: комментарий от rukez

Снова тупишь. Разговор лишь о правомерности использования com.sun.* в коде.

Ты не увиливай, а расскажи свою «официальную версию» разделения

Подмена темы разговора - один из приёмов демагогов.

Отправь им телефакс с вопросом, раз в телефонограммы не умеешь

Смени профессию, у тебя талант клоуна.

А и в правду, как так возмутительно явадок на ораклждк попал на сайт оракл? А теперь назови ещё пару жвм6, в которых были эти классы. Для закрепления попробуй добавить этот класс в экслипсе с таргетом на яву 8 или ниже и посмотри что он тебе напишет

Для закрепления моего впечатления, что ты туп, хамовит и годен лишь для выступлений в цирке я таки запустил завалявшийся Eclipse 2020-09 и следующий код в нём:

package com.example;

import java.io.IOException;

import com.sun.net.httpserver.HttpServer;

public class TestClass {
	
    public static void main(String[] args) throws IOException {
        HttpServer server = HttpServer.create();
        System.out.println(server);
        System.out.println(System.getProperty("java.version"));
    }

}

Код скомпилировался и отработал, выдав:

sun.net.httpserver.HttpServerImpl@49476842
1.8.0_281

А ты ожидал, что Eclipse это не скомпилирует или будет как-то ещё ругаться? Телефонографируй разработчикам, как ты выше предлагал.

Я сдаюсь, ты реально непробиваем, продолжай юзать буты, саны, лёд для пердака, просто не пиши ничего опасного для людей :-)

Ты уже записался к психиатру?

hummer
() автор топика
Последнее исправление: hummer (всего исправлений: 2)
Ответ на: комментарий от rukez

Да никто и не говорит что он был не доступен, он просто не часть языка и не обязательная часть jvm - ты можешь сделать se1.6 совместимую жвм БЕЗ этого класса и никто не в праве тебе после этого сказать что она не 1.6 совместима

Ты снова тупишь. Никто не пытался утверждать, что com.sun.* - это часть стандартного Java API. Однако это так же не закрытая внутренняя часть JRE и её вполне можно использовать, поскольку даже если её выпилят из JRE, из неё сделают отдельную библиотеку, которую ты сможешь использовать. Но в данном случае com.sun.jndi.ldap.LdapCtxFactory просто не стали экспортировать, закрыв внутри соответствующего модуля.

Это из Java 11:

module java.naming {
    requires java.security.sasl;

    exports javax.naming;
    exports javax.naming.directory;
    exports javax.naming.event;
    exports javax.naming.ldap;
    exports javax.naming.spi;

    exports com.sun.jndi.toolkit.ctx to
        jdk.naming.dns;
    exports com.sun.jndi.toolkit.url to
        jdk.naming.dns,
        jdk.naming.rmi;
    exports com.sun.jndi.ldap to
        jdk.naming.ldap;

    uses javax.naming.ldap.StartTlsResponse;
    uses javax.naming.spi.InitialContextFactory;

    provides java.security.Provider with
        sun.security.provider.certpath.ldap.JdkLDAP;
}

Это из Java 16

module java.naming {
    requires java.security.sasl;

    exports javax.naming;
    exports javax.naming.directory;
    exports javax.naming.event;
    exports javax.naming.ldap;
    exports javax.naming.spi;
    exports javax.naming.ldap.spi;

    exports com.sun.jndi.toolkit.ctx to
        jdk.naming.dns;
    exports com.sun.jndi.toolkit.url to
        jdk.naming.dns,
        jdk.naming.rmi;

    uses javax.naming.ldap.StartTlsResponse;
    uses javax.naming.spi.InitialContextFactory;
    uses javax.naming.ldap.spi.LdapDnsProvider;

    provides java.security.Provider with
        sun.security.provider.certpath.ldap.JdkLDAP;
}

Просто exports com.sun.jndi.ldap убрали.

hummer
() автор топика
Последнее исправление: hummer (всего исправлений: 1)
Ответ на: комментарий от hummer

https://www.oracle.com/java/technologies/faq-sun-packages.html

The java.*, javax.* and org.* packages documented in the Java Platform Standard Edition API Specification make up the official, supported, public interface.

If a Java program directly calls only API in these packages, it will operate on all Java-compatible platforms, regardless of the underlying OS platform.

Совместимость вниз поддерживается только для java.*, javax.*, org.*. Для com.sun.* никто не обещает поддержку.

Можно ещё открыть список всех публичных пакетов и классов JDK: https://docs.oracle.com/en/java/javase/16/docs/api/overview-tree.html и убедиться в том, что класса com.sun.jndi.ldap.LdapCtxFactory там нет. Затем в ссылке заменить 16 на 15, 11, открыть список всех классов спецификации и убедиться, что и там этого класса нет. Затем открыть список всех классов из спецификации Java 8: https://docs.oracle.com/javase/8/docs/api/allclasses-noframe.html и убедиться, что этот класс отсутствует и в спецификации Java 8 SE.

Также можно почитать https://openjdk.java.net/jeps/179

There is a long-standing shortcoming in the JDK in terms of clearly specifying the support and stability usage contract for com.sun.* types and other types shipped with the JDK that are outside of the Java SE specification.

usage contract for com.sun.* types and other types shipped with the JDK that are outside of the Java SE specification.

Где английским по белом написано, что com.sun.* вне спецификации Java SE.

А в Java 16 случилось https://openjdk.java.net/jeps/396:

Strongly encapsulate all internal elements of the JDK by default, except for critical internal APIs such as sun.misc.Unsafe. Allow end users to choose the relaxed strong encapsulation that has been the default since JDK 9.

По причине:

Motivation:

All classes, methods, and fields of sun.* packages are internal APIs of the JDK. Some classes, methods, and fields of com.sun.*, jdk.*, and org.* packages are also internal APIs. These APIs were never standard, never supported, and never intended for external use. The use of these internal elements by external code is an ongoing maintenance burden. Time and effort spent preserving these APIs, so as not to break existing code, could be better spent moving the platform forward.

В данном случае по идее можно исправить, если в приложение экспортировать модуль javax.naming. Ну или сделать как сделали товарищи из spring.

ma1uta ★★★
()
Ответ на: комментарий от hummer

тогда можно еще скакать, но на чем-то большем я бы не рискнул.

anonymous
()
Ответ на: комментарий от ma1uta

Судя по всему ты не прочитал всего обсуждения и сразу бросился отвечать и рассказывать о спецификации и о стандартном Java API. Никто не утверждает, что com.sun.* входит в стандартный Java API, но он так же не является внутренним кодом JRE, как sun.*. Перечитай несколько последних сообщений в этой теме. Надеюсь, что до оскорблений, как с rukez, ты не дойдёшь.

в Java 16 случилось https://openjdk.java.net/jeps/396

Там нет ни одного упоминания com.sun.jndi.ldap. Почему экспорт этого пакета убрали, а экспорт com.sun.jndi.toolkit.ctx и com.sun.jndi.toolkit.url оставили?

hummer
() автор топика
Ответ на: комментарий от hummer

это и есть хак, подлатали в одном месте чтобы работало и дальше, никто не думает переписывать весь код в рамках новшеств последнего релиза джавы.

кстати я не могу понять, а зачем ждать то, раз ты все равно пытаешься пока усидеть на около мейнстримном коде, обнови спринг лдап и зависимости до актуальных с патчем.

если не секрет, что это такое вообще где нужен лдап?

anonymous
()
Ответ на: комментарий от anonymous

это и есть хак, подлатали в одном месте чтобы работало и дальше, никто не думает переписывать весь код в рамках новшеств последнего релиза джавы.

Ты про то, как исправили Spring LDAP? Это не хак, а лишь отказ от прямого использования com.sun.jndi.ldap.LdapCtxFactory, который нужел лишь для того, чтобы получить его полное имя.

кстати я не могу понять, а зачем ждать то, раз ты все равно пытаешься пока усидеть на около мейнстримном коде, обнови спринг лдап и зависимости до актуальных с патчем.

В том-то и дело, что Spring LDAP 2.3.4, с исправлением, ещё не вышел.

hummer
() автор топика
Ответ на: комментарий от hummer

Судя по всему ты не прочитал всего обсуждения и сразу бросился отвечать и рассказывать о спецификации и о стандартном Java API. Никто не утверждает, что com.sun.* входит в стандартный Java API, но он так же не является внутренним кодом JRE, как sun.*.

Ещё раз перечитай, пожалуйста, https://openjdk.java.net/jeps/396:

Some classes, methods, and fields of com.sun.*, jdk.*, and org.* packages are also internal APIs. These APIs were never standard, never supported, and never intended for external use.

Т. е. какие-то классы, методы и поля из com.sun.* является internal API, т. е. внутренним API. Я уже молчу, что у классов com.sun.jdni.ldap нет javadoc-ов (хотя тут могу ошибаться, поправь меня, пожалуйста, если я не прав).

Там нет ни одного упоминания com.sun.jndi.ldap.

Some classes, methods, and fields of com.sun.*, jdk.*, and org.* packages are also internal APIs.

Там есть упоминание всех пакетов из com.sun.*, что включает в себя и com.sun.jndi.ldap.

Почему экспорт этого пакета убрали, а экспорт com.sun.jndi.toolkit.ctx и com.sun.jndi.toolkit.url оставили?

Я думаю, что авторы этого изменения могут ответить тебе. Я всего лишь могу предположить, что com.sun.* - помойка, где что-то относится к internal API, что-то к публичном API (как httpserver из модуля jdk.httpserver). И сейчас просто «наводят порядок».

ma1uta ★★★
()
Ответ на: комментарий от ma1uta

В официальной документации, рассказывающей как работать с LDAP в Java, используется полное имя этого класса, примерно так:

    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

Кто-то из разработчиков Spring LDAP видимо решил (и вполне справедливо), что просто имя класса - не есть хорошо, поскольку оно не проверяется во время компиляции и может содержать опечатку. Поэтому изначально там сделали так:

	private static final Class<com.sun.jndi.ldap.LdapCtxFactory> DEFAULT_CONTEXT_FACTORY
            = com.sun.jndi.ldap.LdapCtxFactory.class;

	private Class<?> contextFactory = DEFAULT_CONTEXT_FACTORY;

	private Hashtable<String, Object> setupAnonymousEnv() {
            // some other code

            env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory.getName());

            // some other code
        }

В любом случае com.sun.jndi.ldap.LdapCtxFactory используется и продолжит использоваться в прикладном коде, но лишь по названию. Какой смысл было его закрывать мне не понятно. Если этот класс упоминается в официальной документации, почему закрыли весь com.sun.jndi.ldap, почему не экспортируют хотя бы этот один класс?

hummer
() автор топика
Ответ на: комментарий от hummer

Ты про то, как исправили Spring LDAP? Это не хак, а лишь отказ от прямого использования com.sun.jndi.ldap.LdapCtxFactory, который нужел лишь для того, чтобы получить его полное имя.

Это как принуждение называть свободным выбором :) Изменение в джаве повлекли за собой этот «добровольный» отказ. Именно принуждение к нужде написания обходного пути и является хаком (ты скорее всего просто понимаешь под словом хак, действия более деструктивного характера, когда «через гланды» добиваются работы, тут просто пришлось переписать иначе, но в рамках штатных средств) в данном случае, ты же не будешь возражать против того факта, что старый код превратился в тыкву из рабочего по вине этих изменений в джаве? Я могу согласиться что все обошлось малой кровью, и не так уж сильно все и поломалось, благо джаву развивают все-таки достаточно осторожно.

В том-то и дело, что Spring LDAP 2.3.4, с исправлением, ещё не вышел.

я предлагал не ждать релиза, а воспользоваться уже тем что есть с этим патчем. А как будет релиз так и релиз поставишь. Или все же какую-то степень скреп в виде «пользоваться только релизами» ты стараешься придерживаться?

anonymous
()
Ответ на: комментарий от hummer

Какой смысл было его закрывать мне не понятно.

Как уже сказали ранее, во имя порядочка и против всякого разброда и шатания (что тоже весьма спорно). Также не стоит забывать о священной войне против рефлексии объявленной еще кажется начиная с 8 джавы. Пока остатки кода не переедут на 11+ джаву такие вещи будут происходить с завидным постоянством.

anonymous
()
Ответ на: комментарий от anonymous

Именно принуждение к нужде написания обходного пути и является хаком

Другой бы сказал, что это возврат к рекомендуемому в официальной документации. Ссылку на эту документацию я давал выше. Если и считать тут что-то хаком, так это саму эту документацию, которая рекомендует использовать теперь уже недоступный класс, пусть и по имени.

я предлагал не ждать релиза, а воспользоваться уже тем что есть с этим патчем. А как будет релиз так и релиз поставишь. Или все же какую-то степень скреп в виде «пользоваться только релизами» ты стараешься придерживаться?

Самому собрать Spring LDAP? Меня не поймут.

hummer
() автор топика
Ответ на: комментарий от anonymous

Интересно, когда они уже отменять ключевое слово goto? Борятся непонятно с чем и для чего, а этот никому не нужный анахронизм держат.

hummer
() автор топика
Ответ на: комментарий от hummer

Приятно иметь возможность держать ключевое слово и не использовать его, есть в этом какое-то предосудительное сладострастное удовольствие. Вообще на самом деле гоуту могло быть не так уж и бесполезно есть же кейсы его использования без лапши и по делу.

anonymous
()
Ответ на: комментарий от anonymous

Вообще на самом деле гоуту могло быть не так уж и бесполезно есть же кейсы его использования без лапши и по делу.

Для этих кейсов давно добавили поддержку меток в ключевых словах continue и brake.

hummer
() автор топика
Ответ на: комментарий от hummer

Насколько я помню они работают все же не так как goto, в чем конкретно отличия я уже не помню, но думаю это легко гуглится. То ли они только в рамках конструкции циклов работали то ли что-то такое. В общем типичный для джавы тюнинг соплями языка под хотелки публики.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.