Skip to content

Requiring visibility=PRIVATE for native initialize is error-prone #8210

@headius

Description

@headius

In #8146 we see a side effect of not properly setting up a native #initialize method as private: DelegateClass will attempt to also wrap #initialize, breaking the delegator's constructor path and leading to ArgumentError: not delegated errors.

The issue in that case is that a third-party JRuby extension defines #initialize without any change to visibility, which effectively results in it being public. The immediate fix would be to add visibility = Visibility.PRIVATE to the @JRubyMethod annotation, but this is obviously going to be missed by people unfamiliar with the requirement that #initialize be private. I am opening this bug to consider ways to prevent that from happening in the future.

A few ideas:

  • Warn at runtime if a native #initialize is defined as public. It would be noise on startup, but immediately apparent to any extension writers what they need to do.
  • Always defined #initialize as private, regardless of the annotation.
    • We could possibly allow an exception for when it is explicitly defined as public... but I'm not sure how to detect that. The default in the annotation is already public, so we have no way to know whether it was left unspecified or explicitly set to public.
  • Enhance DelegateClass to always ignore initialize, since delegating it will almost always be wrong and broken. This would make it possible to fix immediately (with a gem release) and dodge the issue of how to handle users that make public #initialize methods.

The workaround is to manually update the visibility of any affected #initialize back to private, as shown in #8146.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions