Missing frame level access modifier

Here is the script. As the creator of open source publicly licensed APIs, my group has created a Java-based user interface platform (so what else is new?). So that everything is well and organized as it should in Java, we used packages with the naming convention org.mygroup.myframework.x, with x being things like components, validators, converters, utilities, etc. (again, what else is new?).

Now, somewhere in the class org.mygroup.myframework.foo.Bar there is a void doStuff() method that I need to execute logic specific to my structure and I need to be able to call it from several other places in mine, for example org .mygroup.myframework.far.Boo. Given that Boo is neither a subclass of Bar, nor in the same package, the doStuff () method must be declared public to call Boo.

However, my infrastructure exists as a tool that allows other developers to create simpler and more elegant RIAs for their customers. But if com.yourcompany.yourapplication.YourComponent calls doStuff (), this can have unexpected and undesirable consequences. I would prefer that this never be allowed. Please note that Bar contains other public methods.

In the ivory tower world, we are rewriting the Java language and inserting the tokenized analogue into standard access, which will allow any class in the package structure of our choice to access my method, perhaps similar to:

 [org.mygroup.myframework.*] void doStuff() { .... } 

where a wildcard will mean that any class whose package starts with org.mygroup.myframework can call, but no one else.

Given that this world does not exist, what other good options do we have?


Note that this is motivated by a realistic scenario; names have been changed to protect the perpetrators. There is a real structure in which, throughout your Javadok, you can find social methods that are commented on as "THIS METHOD IS INTERNAL TO THE MYTHRAME AND NOT A PART OF ITS PUBLIC API. DO NOT CALL !!!!!!" A little research shows that these methods call from other sources within.

In truth, I am a developer using the framework in question. Although our application has been deployed and is successful, my team has experienced so many problems that we want to convince our bosses to never use this structure again. We want to do this in a well-designed presentation of weak design decisions made by the developers of the framework, and not just as a rant. This problem will be one (of several) of our points, but we simply cannot say how we could do it differently. There was already a lively discussion at my workplace, so I wondered what the rest of the world would think.


Update: there are still no offenses for the two defendants, but I think you missed the mark, or I did not express it very well. In any case, I can try to highlight things. Try your best, as the developers of the framework reorganized the following. Please note that this is a really rude example.

 package org.mygroup.myframework.foo; public class Bar { /** Adds a Bar component to application UI */ public boolean addComponentHTML() { // Code that adds the HTML for a Bar component to a UI screen // returns true if successful // I need users of my framework to be able to call this method, so // they can actually add a Bar component to their application UI } /** Not really public, do not call */ public void doStuff() { // Code that performs internal logic to my framework // If other users call it, Really Bad Things could happen! // But I need it to be public so org.mygroup.myframework.far.Boo can call } } 

Another update: So, I just found out that C # has an “internal” access modifier. Therefore, perhaps the best way to formulate this question could be as follows: "How to simulate / emulate internal access in Java?" However, I am not looking for new answers. Our boss eventually agreed with the problems mentioned above.

+8
java access-modifiers design
source share
4 answers

You are closest to the answer when you mention a documentation problem. The real problem is not that you cannot “protect” your internal methods; rather, it is because internal methods pollute your documentation and create a risk that the client module may mistakenly call the internal method.

Of course, even if you have fine faceted permissions, you still cannot prevent the client module from invoking internal methods --- jvm does not protect against calls based on reflection on private methods.

The approach I use is to define an interface for each problem class and implement its class. An interface can only be documented in terms of client modules, while an implementation class can provide the necessary internal documentation. You do not even need to include the javadoc implementation in your distribution package if you do not want this, but in any case, the border is clearly demarcated.

As long as you make sure that only one implementation is loaded at runtime for each documentation interface, modern jvm ensures that you do not get any penalty for using it; and you can download harness / plug versions during testing for an added bonus.

0
source share

The only idea I can think of to provide this missing “platform level access modifier” is CDI and better design. If you need to use a method from a wide variety of classes and packages in various (but few) situations, then there WILL, of course, be a way to reverse engineer these classes to make these methods "private" and inaccessible.

0
source share

There is no support in Java for this level of access (you would like something like "internal" with a namespace). You can restrict access only to the package level (or to the well-known inheritance model protected by private protection).

From my experience you can use the Eclipse convention: create a package called "internal" in which the entire class hierarchy (including subpackages) of this package will be considered a non-API code and can be changed at any time without any guarantees for your users . In this non-API code, use public methods whenever you want. Since this is just a convention and it is not applied by the JVM or the Java compiler, you cannot forbid users to use this code, but at least tell them that these classes are not intended for use by third parties.

By the way, in the source code of the Eclipse platform there is a complex plug-in model, which forces you not to use the internal code of other plug-ins, introducing a custom class loader for each plug-in, which prevents the loading of classes that should be "internal" in these plug-ins.

0
source share

Interfaces and dynamic proxies are sometimes used to make sure that you expose only the methods that you want to open.

However, this is due to fairly high performance if your methods are called very often.

Using the @Deprecated annotation can also be an option, although this does not stop external users calling your "private infrastructure methods", they cannot say that they were not warned.

All in all, I don’t think you should worry that your users intentionally shoot too much in the foot while you let them know that they should not use something.

0
source share

All Articles