Проблемы с загрузкой Spring / spring security / keycloak classloader

#spring-boot #grails #spring-security #classloader #keycloak

#весенняя загрузка #grails #spring-безопасность #загрузчик классов #keycloak

Вопрос:

Я добавил интеграцию с keycloak в существующее приложение Grails 3 (3.3.2), и по большей части оно работает хорошо. Однако я время от времени получаю ClassCastExceptions или GroovyCastExceptions, пытающиеся преобразовать класс Foo в класс Foo.

Я понимаю, что двумя распространенными причинами этого являются повторяющиеся включения класса или многократные загрузки класса в разные загрузчики классов. Я подтвердил с помощью тщательной проверки (дамп кучи и -class: подробный просмотр журнала), что рассматриваемые классы не только существуют только один раз для каждого приложения, но и загружаются только один раз для каждого приложения. В частности, для X запущенных мной приложений рассматриваемый класс загружается ровно X раз, каждый раз другим загрузчиком Webappclass.

Одним из осложняющих факторов является то, что я запускаю несколько приложений (скомпилированных в wars через gradle war ) в одном экземпляре Tomcat. Каждое приложение включает копию jar, в которой найдены классы-нарушители. Я понимаю, что иерархия загрузчика классов tomcat должна позволять это без проблем.

Далее следуют трассировки стека и конфигурация сборки. У кого-нибудь есть предложения по дальнейшему устранению неполадок?

build.gradle

 // relevant parts:
dependencies {
    compile "org.springframework.boot:spring-boot-starter-logging"
    compile "org.grails:grails-core"
    compile "org.springframework.boot:spring-boot-starter-actuator"
    provided "org.springframework.boot:spring-boot-starter-tomcat"
    compile "org.grails:grails-dependencies"
    compile "org.grails:grails-web-boot"
    compile "org.springframework.security:spring-security-core:4.2.3.RELEASE"
    compile "org.springframework.boot:spring-boot-starter-security:1.5.8.RELEASE"
    compile "org.keycloak:keycloak-spring-security-adapter:3.4.3.Final"
}
  

Исключения (усеченные)

 2019-03-14 13:42:39.396 [http-apr-8443-exec-3] ERROR o.s.b.w.s.ErrorPageFilter Forwarding to error page from request [/service/search/config] due to exception [org.grails.web.servlet.mvc.GrailsWebRequest cannot be cast to org.grails.web.servlet.mvc.GrailsWebRequest]
java.lang.ClassCastException: org.grails.web.servlet.mvc.GrailsWebRequest cannot be cast to org.grails.web.servlet.mvc.GrailsWebRequest
        at org.grails.web.servlet.mvc.GrailsWebRequest.lookup(GrailsWebRequest.java:435)
        at org.grails.web.servlet.mvc.GrailsWebRequest.inheritEncodingStateRegistry(GrailsWebRequest.java:127)
        at org.grails.web.servlet.mvc.GrailsWebRequest.<init>(GrailsWebRequest.java:108)
  

и

 2019-03-14 16:06:50.938 [pool-54-thread-1] ERROR StackTrace Full Stack Trace:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'MimeType { name=*/*,extension=all,parameters=[q:1.0] }' with class 'grails.web.mime.MimeType' to class 'grails.web.mime.MimeType'
    at org.grails.web.mime.HttpServletResponseExtension.getMimeTypesInternal(HttpServletResponseExtension.groovy:232)
    at org.grails.web.mime.HttpServletResponseExtension.getMimeTypeForRequest(HttpServletResponseExtension.groovy:147)
    at org.grails.web.mime.HttpServletResponseExtension.getMimeType(HttpServletResponseExtension.groovy:118)
    at org.grails.web.mime.DefaultMimeTypeResolver.resolveResponseMimeType(DefaultMimeTypeResolver.groovy:41)
  

Комментарии:

1. Общей особенностью мест, которые генерируют эти исключения, является то, что (пока) они всегда (Foo) request.getAttribute(whatever) … не уверен, связано ли это или просто обычное место для выполнения приведения классов в grails.

2. Может ли быть так, что сеансы каким-то образом перепутываются, если пользователь переключается с одного веб-приложения на другое?

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

4. Вы когда-нибудь находили решение для этого?

5. К сожалению, нет; в конечном итоге мы перешли к решению без скрытия ключей по другим причинам, и поэтому эта проблема так и не была решена.