Skip to content
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

RepositoryRestMvcConfiguration can no longer be subclassed #1981

Closed
alienisty opened this issue Feb 26, 2021 · 20 comments
Closed

RepositoryRestMvcConfiguration can no longer be subclassed #1981

alienisty opened this issue Feb 26, 2021 · 20 comments
Labels
status: feedback-provided Feedback has been provided

Comments

@alienisty
Copy link

Despite the class documentation states that "To customize how the exporter works, subclass this and override...", that that is no longer possible.
The restHandlerMapping() method returns a DelegatingHandlerMapping which has been made package private in commit d7f36b1 related to DATAREST-1540.
When subclassing RepositoryRestMvcConfiguration for customisation, I now get the following exception:

Caused by: java.lang.IllegalAccessError: failed to access class org.springframework.data.rest.webmvc.config.DelegatingHandlerMapping from class au.com.onyxtech.horus.config.RepositoryRestConfig$ExtendedRepositoryRestMvcConfiguration$$EnhancerBySpringCGLIB$$186fd9d8 (org.springframework.data.rest.webmvc.config.DelegatingHandlerMapping and au.com.onyxtech.horus.config.RepositoryRestConfig$ExtendedRepositoryRestMvcConfiguration$$EnhancerBySpringCGLIB$$186fd9d8 are in unnamed module of loader 'app')
	at au.com.onyxtech.horus.config.RepositoryRestConfig$ExtendedRepositoryRestMvcConfiguration$$EnhancerBySpringCGLIB$$186fd9d8.restHandlerMapping(<generated>)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 89 common frames omitted
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 26, 2021
@odrotbohm
Copy link
Member

What exactly do you need to customize? We usually recommend rather declaring a RepositoryRestMvcConfigurer for general purpose tweaks.

@odrotbohm odrotbohm added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged labels Feb 26, 2021
@alienisty
Copy link
Author

We need to customize:

  1. The auditableBeanWrapperFactory
  2. The linkCollector because the default link format doesn't work for us
  3. The repositoryInvokerFactory because the default one is unaware of entities managed by a polymorphic repository
  4. The persistentEntityJackson2Module

I know that the documentation says that we should override any of the configure* methods, but even then, with the current implementation we are not directly able to do that, and I have a to work around it using a bridge class to make DelegatingHandlerMapping accessible, but that is a bit ugly.

I also know that RepositoryRestConfigurer allows us to customise some things, and we use it, but not all can be done through it.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 27, 2021
@tfleis
Copy link

tfleis commented Mar 8, 2021

We need to add QuerydslPredicateArgumentResolver and our own HandlerMethodArgumentResolver. We have overwritten method RepositoryRestMvcConfiguration.defaultMethodArgumentResolvers.

@steinmaerivoet
Copy link

I'm also running into this problem wanting to override defaultMethodArgumentResolvers to add my custom HandlerMethodArgumentResolver.
My use case is I want to implement https://github.com/sipios/spring-search in Spring Data Rest so I have access to the persistentEntityResourceAssembler.

@MatthieuComtois
Copy link

We need to customize RepositoryInvokerFactory, persistentEntities, persistentEntityJackson2Module, pageableResolver. But implementing RepositoryRestConfigurer doest not allow to override it.

Any solution ?

@MatthieuComtois
Copy link

@alienisty Did you find a clean solution ? I don't get your idea using a bridge class, can you share your solution ?

@alienisty
Copy link
Author

@MatthieuComtois, I had to resort to mokeypatching the problematic class, in my case DelegatingHandlerMapping, and I changed the access level of the class from package private to public.
Monkey patching involve copying the class source and put it in your project source under the same package, so that it will be found before in the classpath substituting the one coming from the framework's jar.
The solution is not ideal because you'll have to update the source every time you upgrade to a newer release.
I hope this helps.

@MatthieuComtois
Copy link

Thanks for the explanation, I will try it, maybe it can help us temporarily

@tgeens
Copy link
Contributor

tgeens commented Jul 8, 2021

I managed to workaround this by using a BeanPostProcessor to replace the beans I wanted to override, instead of subclassing RepositoryRestMvcConfiguration

@odrotbohm
Copy link
Member

We need to customize:

  1. The auditableBeanWrapperFactory
  2. The linkCollector because the default link format doesn't work for us
  3. The repositoryInvokerFactory because the default one is unaware of entities managed by a polymorphic repository
  4. The persistentEntityJackson2Module

None of these components were intended for customization, which is one of the reasons we moved away from the broad exposure of RRMC. Would you folks mind creating tickets for the individual customization requirements, or maybe find already existing ones for us to prioritize? Depending on what those needs look like, there might be a different way to achieve what you want already, or we can introduce better, less low-level means for that.

3 might just have been solved with this ticket as RIF actually uses Repositories to look up the repository to invoke eventually.

@alienisty
Copy link
Author

3 might just have been solved with this ticket as RIF actually uses Repositories to look up the repository to invoke eventually.

I get a 404 on the ticket's link, this one works.

@alienisty
Copy link
Author

We need to customize:

  1. The auditableBeanWrapperFactory

I have raised #2040 for this point

@alienisty
Copy link
Author

We need to customize:

  1. The linkCollector because the default link format doesn't work for us

I have raised #2042 for this point

@alienisty
Copy link
Author

3 might just have been solved with this ticket as RIF actually uses Repositories to look up the repository to invoke eventually.

Yes it is. Confirmed using 2021.1.0-SNAPSHOT

@alienisty
Copy link
Author

We need to customize:

  1. The persistentEntityJackson2Module

Fields annotated with @Version are not exposed but we need the version to support optimistic locking. There is not mechanism similar to optionally exposing an entity id, so we were using a customised PersistentEntityJackson2Module to expose the version field.
If #1809 would be addressed then we would not this this customization.

@odrotbohm
Copy link
Member

Are you aware that the version property is exposed as the ETag header? See the reference documentation for details.

@alienisty
Copy link
Author

Yes I do, but we, currently, only process the response body from the Angular HttpClient. We want to look into improving our adherance to REST principles but that is a long roadmap at this point. Being able to expose the version field would allow us to incrementally "fix" our application.

@odrotbohm
Copy link
Member

Followed up on the original ticket at #1809.

@odrotbohm
Copy link
Member

I'd like to close this one as we've fixed 1 and 2. 3 has been transitively fixed in Spring Data Commons. For 4, we have a discussion in #1809.

@alienisty
Copy link
Author

Sounds good to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided
Projects
None yet
Development

No branches or pull requests

7 participants