1

I am writing some framework code currently. Recently, I had to add some methods to a class which needed to be public because classes outside of that that package need access to it. The clients of that class also have access to that class, but I don't these methods to be accessible by my clients - I just want them to be visible to other framework classes in the framework.

Marking them as public does not help since my clients also have access to it. Marking it as protected or package private does not help since framework classes outside of this class's java package need access to it.

What can I do to solve this problem?

Thanks!

user855
  • 19,048
  • 38
  • 98
  • 162

7 Answers7

1

I don't know what framework you're using, but if you have aspects you could restrict calls to that package based on caller or credentials.

I'm having a hard time reconciling "have access to the class" with "methods not accessible". Which is it? What does access to the class mean if you can't call its methods?

I'd wonder what your framework adds to the world that isn't better available in something like Spring.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • +1 - for the last comment. Far too many people think they need to write yet another Java framework, they are almost always wrong. – Stephen C Oct 09 '12 at 13:32
0

There are no other compile-time checks that you can do, that I can think of. Java doesn't have any other visibility modifiers other than the one you have described.

If you want to limit certain methods to be only accessible by your framework, you should first look at restructuring your framework to use the "package private" visibility level. public has a pretty clear semantics to mean that it is accessible by everybody. If something is only meant to be used by your framework, then it should be protected or "package private" so that no one else can see it.

You could do something at runtime by checking to see which class called your method by using StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(), but this is not going to be perform well (because it creates an exception) and I'd caution against it.

EDIT: There is a slightly more efficient way to figure out the calling class by using the methods described here.

Community
  • 1
  • 1
Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
0

Reading your post reminded of something I read a while ago in apidesign.org called FriendPackages. I have not used this solution but I think it's an interesting read.

madth3
  • 7,275
  • 12
  • 50
  • 74
0

With inheritance when base classes belongs to a "framework" package, declare the "framework-only" method at package visibility.

Only the "framework" package may call them.

Aubin
  • 14,617
  • 9
  • 61
  • 84
0

Couple of solutions:

  1. Define a "public" interface which is the interface your customers knows of, while your class implements another "internal" Interface which extends this "public" interface.
  2. Use some kind of a module management framework like OSGI or Java8 modules.
Guy Korland
  • 9,139
  • 14
  • 59
  • 106
0
  • make a interface called MyService
  • put your favorite methods accessors in that interface.
  • implement two different versions of that. One for the remote, one for the internal use
  • in order to secure your methods, add return new IllegalAccessException() for your client version implementation.
  • use a singleton facade for which implementation will be returned: public static MyService getService(Boolean client)
Hayati Guvence
  • 718
  • 2
  • 6
  • 22
0

There are some interesting and useful suggestions in other Answers, particularly the dual interface idea.

But my take is that you should not be trying too hard to implement access control or enforce API discipline. It is a fact that what ever you do, people will be able to program around any barriers you raise to keep their programs from using "internal" interfaces. The only way you can stop this is by forcing them to run their code in a security sandbox. And I doubt that that would be practical, let alone acceptable.

By all means, try to make it as clear as possible that it is a BAD IDEA for customer code to use your internal APIs. But don't go adding lots of extra code, expensive runtime checks, and other stuff that are going to get in the way. Treat your customers as responsible adults. If they want ignore your strong advice, let them deal with the consequences.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216