5

I'm making an SDK and I'm trying to separate classes to different packages, those classes use some other shared classes. The issue is if I made the shared classes public everyone will be able to see them, not only my classes. What's the right way to make them only accessible by my application?

Example :


Package a MyClass1

Package b MyClass2

Package c public MySharedClass


Because c is public MySharedClass will be able to access it, but the issue is that it will also will be visible to the world, how could I prevent that?

azizbekian
  • 60,783
  • 13
  • 169
  • 249
Jimmy
  • 10,427
  • 18
  • 67
  • 122
  • Possible duplicate: http://stackoverflow.com/questions/4388715/java-expose-only-a-single-package-in-a-jar-file – bacar Mar 07 '12 at 22:24

5 Answers5

4

The packages are all "public" in Java, what you can protect is the classes within a package. For limiting the visibility of a class to only a given package, declare it like this (without the public visibility modifier):

class MyClass {
    // ...
}

In that way, only the classes in the same package as MyClass will be able to see it.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 2
    but by doing this, i have to move all my classes that use that class in the same package. which what i was trying to avoid, if it is possible. – Jimmy Dec 27 '11 at 18:05
  • 1
    Yes. Structure your project in such a way that all the _internal_ (non-public) classes are grouped together in a series of packages, and the public classes are in other package(s). You can expose functionality of the internal classes via public facades in the public package(s). – Óscar López Dec 27 '11 at 18:40
4

Create a package that is documented as an internal package, not to be used by clients.

There is no way in Java to make a class public only for certain packages: It either is public for everyone or package-private (public only in the declared package).

I think there's a proposal for modules to allow better control in the visibility of classes, but we'll have to wait, at least, for Java 8.

Darkhogg
  • 13,707
  • 4
  • 22
  • 24
  • 1
    +1 see also http://stackoverflow.com/questions/4903879/package-names-impl-v-internal and Java 8 Modules == Jigsaw http://www.slideshare.net/mfrancis/java-8-modules-jigsaw-and-osgi-neil-bartlett – Fuhrmanator Nov 21 '12 at 16:12
3

Non trivial:

The shared classes could be defined by a generally accessible set of interfaces. The actual implementation should be loaded explicitly via a Classloader. After that, simply apply Java Security Management mechanisms to control access to the implementation classes. Anyone can see the interfaces and access to actual implementation will be restricted to your SDK.

(A varient of above is what every web/app server needs to do. How do you think Tomcat prevents you from accessing some other app's "public" classes?)

edit: note above is a runtime mechanism. There are static (post) compile approaches as well. APT for example, could be effective here. Naturally I am not addressing a restructuring of your package (in OP) and only addressing how to secure access to a general approach. But these are a bit 'hacky' -- the runtime mechanism of class loading is canonical and imo strictly more correct.

alphazero
  • 27,094
  • 3
  • 30
  • 26
1

If the class is shared by classes from two different packages, it could be a good indication that these two classes should be in the same package, along with the shared class, which wouldn't be public and would thus only be usable by classes of the same package.

If it's really not an option, just document the shared class appropriately, to indicate that it's not supposed to be used outside of the SDK internal code, that it's subject to changes in future versions, and make it even clearer by naming the package "internal" or somthing like this.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • If needed you can even obfuscate your internal classes afterwards. Still visible to your clients, but not really usable anymore. Also, only generate javadoc for your non-internal classes, which makes it pretty obvious for customers not to rely on your internal classes – Robin Dec 27 '11 at 21:09
1

protected modifier can use,in case of your class will access only in same package. otherwise there is no possibility.

sethupathi.t
  • 502
  • 2
  • 6