You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltaspike.apache.org by "Mark Struberg (JIRA)" <ji...@apache.org> on 2018/09/07 10:43:00 UTC

[jira] [Commented] (DELTASPIKE-1333) Support default methods in interface based configuration

    [ https://issues.apache.org/jira/browse/DELTASPIKE-1333?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16606967#comment-16606967 ] 

Mark Struberg commented on DELTASPIKE-1333:
-------------------------------------------

I looked into it and it is not exactly trivial. It would require a subclassing proxy which does _not_ implement default methods. But java.lang.reflect Proxies don't work that way. You cannot turn them off. 

So what happens is that the `invoke(Object proxy, Method m, Object[] args)` method gets called on the proxy. 
Here we could easily detect that this method is actually a default method from the interface. And we could also do a method.invoke() on it. 
But what should we pass? Obviously we have just the proxy. And calling the default method on the proxy we will be back in the InvocationHandler ending up in an endless loop.

In Java7 and 8 there was a somewhat hacky way to solve this via MethodHandlers. See
https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/

Sadly this also doesn't work anymore in Java9. There are other tricks with Java9&10 by using the new MethodHandles findSpecial + privateLookupIn. But those methods do not yet exist in Java8...

Summary: default methods in java.lang.reflect proxies are a pain. There is no consistently working solution. The only viable solution is to generate the proxy ourselves via native bytecode manipulation. I've done this for OpenJPA and OpenWebBeans (got ported over here as well). But this requires a low level bytecode lib like BCEL or ASM. So I'd rather not support it by default

> Support default methods in interface based configuration
> --------------------------------------------------------
>
>                 Key: DELTASPIKE-1333
>                 URL: https://issues.apache.org/jira/browse/DELTASPIKE-1333
>             Project: DeltaSpike
>          Issue Type: Improvement
>          Components: Configuration
>    Affects Versions: 1.8.1
>         Environment: Java 8, DeltaSpike 1.8.1
>            Reporter: Niels Ull Harremoes
>            Assignee: Mark Struberg
>            Priority: Minor
>   Original Estimate: 4h
>  Remaining Estimate: 4h
>
> I wanted to implement a default method in one of my configuration methods as a simple way to configure a Duration:
> {code:java}
> @Configuration
> interface CacheConfig {
>   @ConfigProperty(name = "cache.lifetime", defaultValue = "P1D")
>   String cacheLifetime();
>   default Duration getCacheLifetimeDuration() {
>     try {
>        return Duration.parse(cacheLifetime());
>     } catch (DateTimeParseException e) {
>         ...
>   }
> }
> {code}
> However, a runtime I get the error
> {quote}java.lang.UnsupportedOperationException: public default java.time.Duration com.example.CacheConfig.getLifetimeDuration() doesn't have @ConfigProperty and therefore is illegal
> {quote}
> It would be nice if default methods were not processed.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)