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

Robert Scholte commented on VELOCITY-952:
-----------------------------------------

{code}
public class ModuleVisibilityTest extends BaseTestCase {

        public ModuleVisibilityTest(String name) {
                super(name);
        }
        
        @Override
        protected void setUpContext(VelocityContext context) {
                context.put("timeZone", TimeZone.getTimeZone("UTC"));
        }
        
        public void testModuleVisibilityTest() {
                assertEvalEquals("0","$timeZone.getOffset(0)");
        }

}
{code}

A small testcase to reproduce it. And I think the assumption is right.
In that case, what should be improved is respecting the method return type 
instead of the class of the returned instance.

> Velocity is calling the "wrong" method
> --------------------------------------
>
>                 Key: VELOCITY-952
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-952
>             Project: Velocity
>          Issue Type: Bug
>          Components: Engine
>    Affects Versions: 2.3
>            Reporter: Thomas Mortagne
>            Priority: Major
>
> OK, the title is maybe a bit harsh, but it catches the eyes :)
> At XWiki we recently started testing on Java 17 to see if there is any 
> problem which leaded us to add things like {{--add-opens 
> java.base/java.util=ALL-UNNAMED}} but Velocity happen to be the source of 
> another problem related to the new module world.
> When doing something like {{$datetool.timeZone.getOffset(0)}} ($datetool 
> being the org.apache.velocity.tools.generic.DateTool) we get the following 
> error:
> {noformat}
> ...
> Caused by: java.lang.IllegalAccessException: class 
> org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl cannot 
> access class sun.util.calendar.ZoneInfo (in module java.base) because module 
> java.base does not export sun.util.calendar to unnamed module @7ca16adc
>  at 
> java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
>  at 
> java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
>  at java.base/java.lang.reflect.Method.invoke(Method.java:560)
>  at 
> org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.doInvoke(UberspectImpl.java:571)
>  at 
> org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:554)
>  at 
> org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:221)
>  ... 199 more
> {noformat}
> The reason is that while the developer intent/expectation was to call 
> "java.util.TimeZone#getOffset(0)" what Velocity really called from JVM point 
> of view is "sun.util.calendar.ZoneInfo.getOffset(0)" directly.
> That's because Velocity is doing (I assume, since I did not check the exact 
> code) the equivalent of:
> {{noformat}}
> java.util.TimeZone.getDefault().getClass().getMethod("getOffset", 
> long.class).invoke(TimeZone.getDefault(), 0);
> {{noformat}}
> which is itself the equivalent of:
> {{noformat}}
> sun.util.calendar.ZoneInfo.class.getMethod("getOffset", 
> long.class).invoke(TimeZone.getDefault(), 0);
> {{noformat}}
> I guess the only way to fix this would be to track down the lowest overridden 
> Method (I agree, it might not always be easy to choose between two interfaces 
> declaring a method with the same signature, but choosing the first one we 
> find from the same hierarchy level is still better than nothing) and call 
> that one instead. With the use case used as example in this issue, that would 
> mean ending up doing the equivalent of:
> {{noformat}}
> java.util.TimeZone.class.getMethod("getOffset", 
> long.class).invoke(TimeZone.getDefault(), 0);
> {{noformat}}
> which, from JVM point of view, is covered by the {{--add-opens 
> java.base/java.util=ALL-UNNAMED}}.
> It would be a big change, but at least can't think of any retro-compatibility 
> problem it might cause.
> One might be tempted to answer "just add {{--add-opens 
> java.base/sun.util.calendar=ALL-UNNAMED}}" but it does not seem fair as this 
> is not what the API that the script uses was exposing at all, you might need 
> to document a different one for each JVM implementation (even if it's 
> probably unlikely for this specific example) but more importantly you will 
> potentially need quite a lot of those and will only discover it at runtime 
> since it's not so easy to guess from an API in which you only know the public 
> JVM classes since that's what you manipulate.
> I would be happy to work on this, but I wanted first ask what others think 
> about this problem in general and the possible solutions I may have missed.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@velocity.apache.org
For additional commands, e-mail: dev-h...@velocity.apache.org

Reply via email to