-1

This follows on from this question, which is about Groovy (a superset/modernisation of Java), where there is, seemingly, essentially no information-hiding and no encapsulation whatsoever.

But in Java too of course there is reflection, meaning that private, protected and package-private are essentially pointless, or worse: create a false sense of security.

In Java, is there any way to enforce visibility, of some kind, not necessarily in the sense of specifically enforcing the above visibility modifiers, and package-private, using a SecurityManager? I've only just started looking into the latter and I can't see any very obvious way of accomplishing something like that. But it would seem that some developers must ship code where some classes and methods do not have completely public visibility... so how is it done?

PS in the Lucene package, with which I'm a bit familiar, I notice that quite a lot of classes turn out to be final (which has sometimes caused me some head-scratching...) but I'm pretty sure, although not certain, that reflection can be used to squash that modifier

mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • Can you narrow down the scope where you want to "enforce visibility"? On company level? For any software out there? Just for your own project? Because for most of those things it's really just a matter of... "if having everything public is what you want to do (no matter if that's the "correct" thing to do) then just make sure everything is made public". – Ben Jun 15 '18 at 07:20
  • The trouble with that question is that it is questioning the intrinsic desirability of encapsulation and information-hiding. I refer you to *Effective Java* by Bloch. – mike rodent Jun 15 '18 at 07:23
  • I upvoted because I agree this is not a stupid question. However, I don't really see the point of what you are trying to achieve. Are you afraid of someone hacking your bytecode? What do you need exactly that SecurityManager cannot provide? – Guilherme Mussi Jun 15 '18 at 07:26
  • @GuilhermeMussi Perhaps I didn't make myself clear, although it seems so to me: I **don't understand** how to use `SecurityManager` to enforce visibility. How does one do that, if it is indeed possible? – mike rodent Jun 15 '18 at 07:28
  • Thanks for the clarification. I added an answer. – Guilherme Mussi Jun 15 '18 at 07:49

1 Answers1

1

Can I write my classes to be setAccessible-proof regardless of SecurityManager configuration? ... Or am I at the mercy of whoever manages the configuration?

You can't and you most certainly are. Anybody who has access to your code can configure their JVM and SecurityManager as they please. (more details below)

Is setAcessible legitimate? Why does it exist?

The Java core classes use it as an easy way to access stuff that has to remain private for security reasons. As an example, the Java Serialization framework uses it to invoke private object constructors when deserializing objects. Someone mentioned System.setErr, and it would be a good example, but curiously the System class methods setOut/setErr/setIn all use native code for setting the value of the final field.

Another obvious legitimate use are the frameworks (persistence, web frameworks, injection) that need to peek into the insides of objects.

And finally...

Java access modifiers are not intended to be a security mechanism.

So what can I actually do?

You should take a deeper look into Security Providers section of the Java SE Security documentation:

Applications do not need to implement security themselves. Rather, they can request security services from the Java platform. Security services are implemented in providers

The access control architecture in the Java platform protects access to sensitive resources (for example, local files) or sensitive application code (for example, methods in a class). All access control decisions are mediated by a security manager, represented by the java.lang.SecurityManager class. A SecurityManager must be installed into the Java runtime in order to activate the access control checks.

Java applets and Java™ Web Start applications are automatically run with a SecurityManager installed. However, local applications executed via the java command are by default not run with a SecurityManager installed. In order to run local applications with a SecurityManager, either the application itself must programmatically set one via the setSecurityManager method (in the java.lang.System class), or java must be invoked with a -Djava.security.manager argument on the command line.

I recommend you read further about this on the official security documentation

https://docs.oracle.com/javase/7/docs/technotes/guides/security/overview/jsoverview.html

Guilherme Mussi
  • 956
  • 7
  • 14
  • Er, OK, thanks. But I have already started looking into `SecurityManager`. Again, my question makes that plain. I am asking a very specific thing: ***HOW*** might I use `SecurityManager` to enforce, SPECIFICALLY, **visibility**? You really need to reread my question a bit more carefully. – mike rodent Jun 15 '18 at 07:53
  • As I wrote, you cannot. There is no way to prevent this. Maybe you can tell a bit more about your use case. Why do you need this? Because anybody who gets your code can implement their own SecurityManager. – Guilherme Mussi Jun 15 '18 at 07:57
  • For the sake of argument let us assume I am in charge of my `SecurityManager`. My case is specific only in the sense that I am a Groovy user (Groovy = superset/modernisation of Java). The desirability of information-hiding and encapsulation doesn't need to be justified. The problem is that visibility modifiers are essentially ignored in Groovy. – mike rodent Jun 15 '18 at 08:03