New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove bean overriding in Activiti Cloud Starters #2201

Closed
salaboy opened this Issue Nov 25, 2018 · 9 comments

Comments

2 participants
@salaboy
Member

salaboy commented Nov 25, 2018

Every starter in Activiti Cloud is now adding the bean override property:

spring.main.allow-bean-definition-overriding=true

We need to remove this which is caused by the keycloak spring boot starter extension inside activiti cloud common. Bean override is disabled by default in spring boot 2.1 so we should avoid it.

@salaboy salaboy added this to the Beta4 milestone Nov 25, 2018

@salaboy salaboy added this to Open in Activiti 7.x via automation Nov 25, 2018

@salaboy

This comment has been minimized.

Member

salaboy commented Nov 25, 2018

Error that highlight the issue if bean override is removed:

Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'httpSessionManager' defined in class path resource 
[org/activiti/cloud/services/common/security/keycloak/config/CommonSecurityAutoConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; 
autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; 
factoryBeanName=commonSecurityAutoConfiguration; factoryMethodName=httpSessionManager; 
initMethodName=null; destroyMethodName=(inferred); defined in class path resource 
[org/activiti/cloud/services/common/security/keycloak/config/CommonSecurityAutoConfiguration.class
]] for bean 'httpSessionManager': There is already [Generic bean: class [org.keycloak.adapters.springsecurity.management.HttpSessionManager]; scope=singleton; 
abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; 
primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; 
destroyMethodName=null; defined in URL [jar:file:/home/travis/.m2/repository/org/keycloak/keycloak-spring-security-adapter/4.6.0.Final/keycloak-spring-security-adapter-
4.6.0.Final.jar!/org/keycloak/adapters/springsecurity/management/HttpSessionManager.class]] bound.

@salaboy salaboy modified the milestones: Beta4, Beta5 Nov 25, 2018

@ryandawsonuk

This comment has been minimized.

Member

ryandawsonuk commented Nov 27, 2018

Have tried simply removing this class and the code referencing it in rb-service and query-service. But am finding that tests fail with:

Caused by: java.io.FileNotFoundException: class path resource [org/activiti/cloud/services/common/security/keycloak/config/CommonSecurityAutoConfiguration.class] cannot be opened because it does not exist
	at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
	at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:51)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:88)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:75)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81)
	at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClass.getAnnotationMetadata(AutoConfigurationSorter.java:241)
	... 54 common frames omitted
2018-11-27 19:55:28,263 [main|org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker] INFO  Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$9007c8e5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

Not sure how as have removed from local maven repo and the class is not required during compilation (this is a runtime error) or shown as on the classpath in IntelliJ. Will investigate further.

@salaboy

This comment has been minimized.

Member

salaboy commented Nov 28, 2018

@ryandawsonuk that is because you are still pointing to that config from a META-INF/spring.factories file :)

@ryandawsonuk

This comment has been minimized.

Member

ryandawsonuk commented Nov 28, 2018

Yeah, thanks, I should've spotted that straight away.

@ryandawsonuk

This comment has been minimized.

Member

ryandawsonuk commented Nov 28, 2018

The problem then moves on to:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adapterDeploymentContext' defined in class path resource [org/activiti/cloud/services/identity/keycloak/config/RuntimeBundleSecurityAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.keycloak.adapters.AdapterDeploymentContext]: Factory method 'adapterDeploymentContext' threw exception; nested exception is java.io.FileNotFoundException: Unable to locate Keycloak configuration file: keycloak.json

Am currently trying this with references to CommonSecurityAutoConfiguration removed from RuntimeBundleSecurityAutoConfiguration It seems it is now looking for the configuration like auth server url to come from a json file rather than the properties file. This seems to mean that a KeycloakConfigResolver isn't getting autowired in anymore.

@ryandawsonuk

This comment has been minimized.

Member

ryandawsonuk commented Nov 28, 2018

There is already a keycloak issue for this - https://issues.jboss.org/browse/KEYCLOAK-8813 After looking at the reason why this change was made in boot So in theory it should be straightforward to fix this in the keycloak adapter with an @ConditionalOnMissingBean on HttpSessionManager

@ryandawsonuk

This comment has been minimized.

Member

ryandawsonuk commented Nov 28, 2018

I've tried overriding this class locally and but then I get the below in the integration tests (i.e. with -DskipITs=false)

javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:394)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:286)
	at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:435)
	at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:102)
	at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
	at com.sun.proxy.$Proxy254.grantToken(Unknown Source)
	at org.keycloak.admin.client.token.TokenManager.grantToken(TokenManager.java:89)
	at org.keycloak.admin.client.token.TokenManager.getAccessToken(TokenManager.java:69)
	at org.activiti.cloud.services.test.identity.keycloak.interceptor.KeycloakTokenProducer.getAccessTokenResponse(KeycloakTokenProducer.java:68)
	at org.activiti.cloud.services.test.identity.keycloak.interceptor.KeycloakTokenProducer.getTokenString(KeycloakTokenProducer.java:72)
	at org.activiti.cloud.services.test.identity.keycloak.interceptor.KeycloakTokenProducer.intercept(KeycloakTokenProducer.java:58)
	at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:92)
	at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:76)
	at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
	at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:734)
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:669)
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:607)
	at org.springframework.boot.test.web.client.TestRestTemplate.exchange(TestRestTemplate.java:843)
	at org.activiti.cloud.starter.tests.runtime.TaskVariablesIT.getProcessDefinitions(TaskVariablesIT.java:150)
	at org.activiti.cloud.starter.tests.runtime.TaskVariablesIT.setUp(TaskVariablesIT.java:74

However, I don't think this particular error is related as I actually see the same issue even without the @ConditionalOnMissingBean and with spring.main.allow-bean-definition-overriding=true. I don't see the same problem on develop builds on travis though so must relate to my local configuration somehow. I see it even after reverting all changes and deleting all activiti and keycloak from my local maven repo. Also same with query-service on latest develop.

Have also tried removing all my local docker images in case it is related to activiti-keycloak image but still get the same error.

@ryandawsonuk

This comment has been minimized.

Member

ryandawsonuk commented Nov 28, 2018

Turns out the Unable to invoke request was just an unrelated problem with picking up an old version of the activiti-keycloak docker image used by the integration tests under latest. I've pushed a new version of that to prevent that affecting others.

Now overriding the keycloak class and adding the ConditionalOnMissingBean does work for both rb-service and query-service and allows us to remove the use of spring.main.allow-bean-definition-overriding. However, this loading happens in the keycloak springsecurity adapter rather than the boot adapter and it doesn't actually use boot deps like ConditionalOnMissingBean. So instead I've tried excluding the component from the ComponentScan and that also works.

Activiti 7.x automation moved this from Closed to Open Nov 30, 2018

@ryandawsonuk

This comment has been minimized.

Member

ryandawsonuk commented Nov 30, 2018

Was able to resolve this without overriding any keycloak class by just adding the ConditionalOnMissingBean in a method of our configuration class that extends a keycloak class. Have created a PR on the keycloak documentation so that others can do likewise. Need to now also resolve this internal one that only seems to affect example layer

Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'metadataService' defined in class path resource [org/activiti/cloud/services/metadata/ActivitiMetadataAutoConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=activitiMetadataAutoConfiguration; factoryMethodName=metadataService; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/activiti/cloud/services/metadata/ActivitiMetadataAutoConfiguration.class]] for bean 'metadataService': There is already [Generic bean: class [org.activiti.cloud.services.metadata.MetadataService]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment