I would like to be able to write a Java class in one package which can access non-public methods of a class in another package without having to make it a subclass of the other class. Is this possible?
18 Answers
Here is a small trick that I use in JAVA to replicate C++ friend mechanism.
Lets say I have a class Romeo
and another class Juliet
. They are in different packages (family) for hatred reasons.
Romeo
wants to cuddle
Juliet
and Juliet
wants to only let Romeo
cuddle
her.
In C++, Juliet
would declare Romeo
as a (lover) friend
but there are no such things in java.
Here are the classes and the trick :
Ladies first :
package capulet;
import montague.Romeo;
public class Juliet {
public static void cuddle(Romeo.Love love) {
Objects.requireNonNull(love);
System.out.println("O Romeo, Romeo, wherefore art thou Romeo?");
}
}
So the method Juliet.cuddle
is public
but you need a Romeo.Love
to call it. It uses this Romeo.Love
as a "signature security" to ensure that only Romeo
can call this method and checks that the love is real so that the runtime will throw a NullPointerException
if it is null
.
Now boys :
package montague;
import capulet.Juliet;
public class Romeo {
public static final class Love { private Love() {} }
private static final Love love = new Love();
public static void cuddleJuliet() {
Juliet.cuddle(love);
}
}
The class Romeo.Love
is public, but its constructor is private
. Therefore anyone can see it, but only Romeo
can construct it. I use a static reference so the Romeo.Love
that is never used is only constructed once and does not impact optimization.
Therefore, Romeo
can cuddle
Juliet
and only he can because only he can construct and access a Romeo.Love
instance, which is required by Juliet
to cuddle
her (or else she'll slap you with a NullPointerException
).

- 9,247
- 5
- 29
- 44
-
Follow up: I'm a Java newb, so I'm guessing there isn't an attribute (annotation?) that could be used to enforce that the "Romeo.Love" parameter to "cuddle" can not be null? Something similar to '__attribute__((nonnull))' in many C compilers? That would make this the perfect solution IMHO (as is it's still awesome). – Steazy Jul 24 '14 at 20:15
-
157+1 for "slap you with a NullPointerException". Very impressive. – Nickolas Aug 04 '14 at 09:09
-
2@Steazy There is : look for the NotNull, NonNull and CheckForNull annotations. Check with your IDE's documentation to find out how to use and enforce those annotations. I know that IntelliJ embeds this by default and that eclipse needs a plugin (such as FindBugs). – Salomon BRYS Aug 20 '14 at 15:41
-
1@ChrisNash You can't. Juliet must declare an accessor: `public Whatever getPrivateField(Romeo.Love l) { l.hashCode(); return mPrivateField; }`. – Salomon BRYS Aug 13 '15 at 10:31
-
46You can make `Romeo`'s `Love` for `Julia` everlasting by changing the `love` field to be `final` ;-). – Matthias Nov 10 '15 at 15:38
-
1... and if you think `Romeo` was into rastafarian "one `Love`" you can make the `love` field `static` as well ;-). – Matthias Nov 10 '15 at 15:42
-
7@Matthias The love field is static... I'll edit the answer to make it final ;) – Salomon BRYS Nov 10 '15 at 16:13
-
6Another cool trick to make this even more elegant (albeit possibly also confusing) is to rename the `love` field to `Love`. Yes, you can actually do this (see http://stackoverflow.com/a/14027255/1084488). The result will be that mentions of "`Love`" in `Romeo`'s code (e.g. in `Juliet.cuddle(Love);`) will be interpreted as references to *his* everlasting, one `Love` object(!), whereas mentions of `Romeo.Love` outside of the `Romeo` class will refer to the public `Love` class(!). – Matthias Nov 10 '15 at 16:51
-
1weren't my [voting system suggestion](http://meta.stackexchange.com/questions/269777/what-about-a-more-flexible-voting-system-favorites-bookmarks-kudos-and-even-s) been so rejected, this answer would score "inspiring 5 stars" and "ingenious 5 stars", as you managed to use good humor and still provide an excelent out of the box alternative :) – Aquarius Power Dec 19 '15 at 18:55
-
do you have any tip for [this question](http://stackoverflow.com/questions/34822434/composite-inheritance-how-to-assign-a-final-field-at-sub-class-constructor-whic?noredirect=1#comment57387508_34822434)? it is related to your answer idea, thx! – Aquarius Power Jan 16 '16 at 01:40
-
19All answers should be like this (Y) +1 for the humor and great example. – Zia Ul Rehman Mughal Apr 24 '16 at 12:15
-
2Totally agree, not only this answer is a great answer, but it provide a simple yet efficient context to remember this "pattern". Great Job. – Stephane Toussaint May 18 '16 at 19:37
-
3A whole new meaning for the phrase "My code is poetry" – mgarciaisaia Sep 20 '16 at 19:27
-
4The most fantastic answer I've ever read in SO. +1 for making Romeo's love everlasting by `final` qualifier ;) – faghani Oct 10 '16 at 13:27
-
1Super late to this party, but I have to say: this is the most glorious piece of stackedit prose I've ever read. BRAVO. I SAY BRAVO, GOOD SIR! – Bryan Shaw Nov 30 '17 at 17:32
-
Beautiful! While the necessity of a pattern like this is usually a strong hint at a design smell, we can't always do big refactorings right away when something smells fishy. In those cases, this solution is as elegant as it gets. – chris Aug 27 '18 at 14:33
-
I really love the answer, but I was wondering if it's possible to make it resist instantiation by reflection (as done by Gson, for example). If not, anyone can create a `Romeo.Love` object. – noamtm Jun 07 '20 at 06:29
-
@noamtm There's not much you can do against reflection. By design, reflection allows you to do virtually anything, including calling private methods. – Salomon BRYS Jun 28 '20 at 09:04
-
@Salomon BRYS, I't's very impressive, but I think it doesn't work. What about a Fake Romeo class (let's call it Iago) that would have a Iago.Love member that is not constructed by itself, but is stolen from Romeo (as it is public). Something like : private static final Love love = Rome.love – mgueydan Sep 25 '20 at 10:36
-
Lago can't construct a Romeo.Love (private constructor), nor access Romeo.love (private property). – Salomon BRYS Sep 25 '20 at 15:38
-
Couldn't this be played by Casting another object to `Romeo.Love` ? – Dávid Tóth Jan 27 '21 at 12:00
-
Note that that mechanism/idiom ([Passkey idiom](https://arne-mertz.de/2016/10/passkey-idiom/)) can also be done in C++ (as it gives access to only some part of the class, and not the whole class). – Jarod42 Feb 11 '21 at 11:00
-
"and checks that the love is real so that the runtime will throw a NullPointerException if it is null". Fantastic. – zombieParrot Oct 15 '22 at 12:25
The designers of Java explicitly rejected the idea of friend as it works in C++. You put your "friends" in the same package. Private, protected, and packaged security is enforced as part of the language design.
James Gosling wanted Java to be C++ without the mistakes. I believe he felt that friend was a mistake because it violates OOP principles. Packages provide a reasonable way to organize components without being too purist about OOP.
NR pointed out that you could cheat using reflection, but even that only works if you aren't using the SecurityManager. If you turn on Java standard security, you won't be able to cheat with reflection unless you write security policy to specifically allow it.

- 6,249
- 4
- 33
- 31
-
14I don't mean to be a pedant, but access modifiers aren't a security mechanism. – Greg D Oct 08 '08 at 12:45
-
6Access modifiers are part of the java security model. I was specifically referring to java.lang.RuntimePermission for reflection: accessDeclaredMembers and accessClassInPackage. – David G Oct 08 '08 at 18:10
-
61If Gosling really thought that `friend` violated OOP (in particular, more than package access does) then [he really didn’t understand it](http://www.parashift.com/c++-faq-lite/friends.html#faq-14.2) (entirely possible, many people misunderstand it). – Konrad Rudolph May 27 '11 at 15:49
-
12Class components sometimes need to be separated (e.g. implementation and API, core object and adapter). Package-level protection is at the same time too permissive and too restrictive to do this properly. – dhardy Feb 12 '14 at 10:43
-
3@GregD They *could* be considered a security mechanism in the sense that they help to prevent developers from using a class member incorrectly. I think they'd probably better be referred to as a **safety mechanism**. – crush Aug 23 '14 at 16:57
-
I simply had to upvote, for the writing and the creative solution. However, I hope that I will never be in the need to do such things in production. – kap Oct 09 '20 at 11:03
The 'friend' concept is useful in Java, for example, to separate an API from its implementation. It is common for implementation classes to need access to API class internals but these should not be exposed to API clients. This can be achieved using the 'Friend Accessor' pattern as detailed below:
The class exposed through the API:
package api;
public final class Exposed {
static {
// Declare classes in the implementation package as 'friends'
Accessor.setInstance(new AccessorImpl());
}
// Only accessible by 'friend' classes.
Exposed() {
}
// Only accessible by 'friend' classes.
void sayHello() {
System.out.println("Hello");
}
static final class AccessorImpl extends Accessor {
protected Exposed createExposed() {
return new Exposed();
}
protected void sayHello(Exposed exposed) {
exposed.sayHello();
}
}
}
The class providing the 'friend' functionality:
package impl;
public abstract class Accessor {
private static Accessor instance;
static Accessor getInstance() {
Accessor a = instance;
if (a != null) {
return a;
}
return createInstance();
}
private static Accessor createInstance() {
try {
Class.forName(Exposed.class.getName(), true,
Exposed.class.getClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
return instance;
}
public static void setInstance(Accessor accessor) {
if (instance != null) {
throw new IllegalStateException(
"Accessor instance already set");
}
instance = accessor;
}
protected abstract Exposed createExposed();
protected abstract void sayHello(Exposed exposed);
}
Example access from a class in the 'friend' implementation package:
package impl;
public final class FriendlyAccessExample {
public static void main(String[] args) {
Accessor accessor = Accessor.getInstance();
Exposed exposed = accessor.createExposed();
accessor.sayHello(exposed);
}
}

- 30,874
- 30
- 96
- 127
-
1Because I didn't know what the "static" means in "Exposed" class: The static block, is a block of statement inside a Java class that will be executed when a class is first loaded in to the JVM Read more at http://www.javatutorialhub.com/java-static-variable-methods.html#VlA0qtKsqfFuFo8r.99 – Guy L Apr 07 '13 at 21:03
-
Interesting pattern but it requires the Exposed and Accessor classes to be public while the classes implementing an API (i.e., a set of Java classes implementing a set of public Java interfaces) would better be "default protected" and, thus, inaccessible to the client to separate types from their implementations. – Yann-Gaël Guéhéneuc May 26 '14 at 10:00
-
8I'm fairly rusty on my Java, so forgive my ignorance. What is the advantage of this over the "Romeo and Juliet" solution Salomon BRYS posted? This implementation would scare the pants off of me if I stumbled on it in a code base (without your explanation attached, ie. heavy commenting). The Romeo and Juliet approach is very simple to understand. – Steazy Jul 24 '14 at 20:06
-
1This approach will make problems visible only at runtime, while Romeo and Juliet misuse would make them visible at compile time, while developing. – ymajoros Jan 18 '17 at 14:03
-
1@ymajoros The Romeo and Juliet example doesn't make misuse visible at compile-time. It relies an an argument being passed correctly, and an exception being thrown. Those are both run-time actions. – Radiodef Aug 24 '18 at 16:07
-
I think this example could be simplified quite a bit, by making the `Accessor` be a public static nested class of `Enclosed` with a private constructor and public methods. Then just inject `Accessor` instances to the friends like you're already doing. Classes in other packages would only be able to use an accessor if they had one injected. I don't think there's much benefit to putting an accessor superclass in the friend package, because you have to make the methods protected which means they're visible to the outside world anyway e.g. via JavaDocs. – Radiodef Aug 24 '18 at 16:12
-
@Radiodef the question seems to be about a compile-time way to find out about misuses (something like a 'friend' operator). This example is indeed about runtime checks, so it's not really suitable. – ymajoros Aug 27 '18 at 12:16
-
@ymajoros I don't know what that has to do with what I said. This answer does actually provide compile-time checks, though, unlike the Romeo and Juliet example. In this example, the methods of `Exposed` are not visible to other packages, and the methods of the accessor are protected, so they're only accessible to the friend package. Those are actually compile-time checks. – Radiodef Aug 27 '18 at 14:50
There are two solutions to your question that don't involve keeping all classes in the same package.
The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).
The second is to use OSGi. There is an article here explaining how OSGi accomplishes this.

- 1
- 1

- 27,676
- 31
- 147
- 246
As far as I know, it is not possible.
Maybe, You could give us some more details about Your design. Questions like these are likely the result of design flaws.
Just consider
- Why are those classes in different packages, if they are so closely related?
- Has A to access private members of B or should the operation be moved to class B and triggered by A?
- Is this really calling or is event-handling better?

- 5,022
- 2
- 22
- 37
Here's a clear use-case example with a reusable Friend
class. The benefit of this mechanism is simplicity of use. Maybe good for giving unit test classes more access than the rest of the application.
To begin, here is an example of how to use the Friend
class.
public class Owner {
private final String member = "value";
public String getMember(final Friend friend) {
// Make sure only a friend is accepted.
friend.is(Other.class);
return member;
}
}
Then in another package you can do this:
public class Other {
private final Friend friend = new Friend(this);
public void test() {
String s = new Owner().getMember(friend);
System.out.println(s);
}
}
The Friend
class is as follows.
public final class Friend {
private final Class as;
public Friend(final Object is) {
as = is.getClass();
}
public void is(final Class c) {
if (c == as)
return;
throw new ClassCastException(String.format("%s is not an expected friend.", as.getName()));
}
public void is(final Class... classes) {
for (final Class c : classes)
if (c == as)
return;
is((Class)null);
}
}
However, the problem is that it can be abused like so:
public class Abuser {
public void doBadThings() {
Friend badFriend = new Friend(new Other());
String s = new Owner().getMember(badFriend);
System.out.println(s);
}
}
Now, it may be true that the Other
class doesn't have any public constructors, therefore making the above Abuser
code impossible. However, if your class does have a public constructor then it is probably advisable to duplicate the Friend class as an inner class. Take this Other2
class as an example:
public class Other2 {
private final Friend friend = new Friend();
public final class Friend {
private Friend() {}
public void check() {}
}
public void test() {
String s = new Owner2().getMember(friend);
System.out.println(s);
}
}
And then the Owner2
class would be like this:
public class Owner2 {
private final String member = "value";
public String getMember(final Other2.Friend friend) {
friend.check();
return member;
}
}
Notice that the Other2.Friend
class has a private constructor, thus making this a much more secure way of doing it.

- 2,870
- 1
- 34
- 36
eirikma's answer is easy and excellent. I might add one more thing: instead of having a publicly accessible method, getFriend() to get a friend which cannot be used, you could go one step further and disallow getting the friend without a token: getFriend(Service.FriendToken). This FriendToken would be an inner public class with a private constructor, so that only Service could instantiate one.

- 31
- 1
The provided solution was perhaps not the simplest. Another approach is based on the same idea as in C++: private members are not accessible outside the package/private scope, except for a specific class that the owner makes a friend of itself.
The class that needs friend access to a member should create a inner public abstract "friend class" that the class owning the hidden properties can export access to, by returning a subclass that implement the access-implementing methods. The "API" method of the friend class can be private so it is not accessible outside the class that needs friend access. Its only statement is a call to an abstract protected member that the exporting class implements.
Here's the code:
First the test that verifies that this actually works:
package application;
import application.entity.Entity;
import application.service.Service;
import junit.framework.TestCase;
public class EntityFriendTest extends TestCase {
public void testFriendsAreOkay() {
Entity entity = new Entity();
Service service = new Service();
assertNull("entity should not be processed yet", entity.getPublicData());
service.processEntity(entity);
assertNotNull("entity should be processed now", entity.getPublicData());
}
}
Then the Service that needs friend access to a package private member of Entity:
package application.service;
import application.entity.Entity;
public class Service {
public void processEntity(Entity entity) {
String value = entity.getFriend().getEntityPackagePrivateData();
entity.setPublicData(value);
}
/**
* Class that Entity explicitly can expose private aspects to subclasses of.
* Public, so the class itself is visible in Entity's package.
*/
public static abstract class EntityFriend {
/**
* Access method: private not visible (a.k.a 'friendly') outside enclosing class.
*/
private String getEntityPackagePrivateData() {
return getEntityPackagePrivateDataImpl();
}
/** contribute access to private member by implementing this */
protected abstract String getEntityPackagePrivateDataImpl();
}
}
Finally: the Entity class that provides friendly access to a package private member only to the class application.service.Service.
package application.entity;
import application.service.Service;
public class Entity {
private String publicData;
private String packagePrivateData = "secret";
public String getPublicData() {
return publicData;
}
public void setPublicData(String publicData) {
this.publicData = publicData;
}
String getPackagePrivateData() {
return packagePrivateData;
}
/** provide access to proteced method for Service'e helper class */
public Service.EntityFriend getFriend() {
return new Service.EntityFriend() {
protected String getEntityPackagePrivateDataImpl() {
return getPackagePrivateData();
}
};
}
}
Okay, I must admit it is a bit longer than "friend service::Service;" but it might be possible to shorten it while retaining compile-time checking by using annotations.

- 657
- 5
- 13
-
This doesn't quite work as a normal class in the same package could just getFriend() and then call the protected method bypassing the private one. – user2219808 Jul 05 '17 at 20:57
Not using a keyword or so.
You could "cheat" using reflection etc., but I wouldn't recommend "cheating".

- 30,874
- 30
- 96
- 127

- 402
- 5
- 6
-
3i would consider this such a bad idea that even suggesting it is abhorrent to me. Obviously this is a cludge at best, and should not be part of any design. – shsteimer Nov 25 '08 at 15:42
I think, the approach of using the friend accessor pattern is way too complicated. I had to face the same problem and I solved using the good, old copy constructor, known from C++, in Java:
public class ProtectedContainer {
protected String iwantAccess;
protected ProtectedContainer() {
super();
iwantAccess = "Default string";
}
protected ProtectedContainer(ProtectedContainer other) {
super();
this.iwantAccess = other.iwantAccess;
}
public int calcSquare(int x) {
iwantAccess = "calculated square";
return x * x;
}
}
In your application you could write the following code:
public class MyApp {
private static class ProtectedAccessor extends ProtectedContainer {
protected ProtectedAccessor() {
super();
}
protected PrivateAccessor(ProtectedContainer prot) {
super(prot);
}
public String exposeProtected() {
return iwantAccess;
}
}
}
The advantage of this method is that only your application has access to the protected data. It's not exactly a substitution of the friend keyword. But I think it's quite suitable when you write custom libraries and you need to access protected data.
Whenever you have to deal with instances of ProtectedContainer you can wrap your ProtectedAccessor around it and you gain access.
It also works with protected methods. You define them protected in your API. Later in your application you write a private wrapper class and expose the protected method as public. That's it.

- 11
- 4
In Java it is possible to have a "package-related friendness". This can be userful for unit testing. If you do not specify private/public/protected in front of a method, it will be "friend in the package". A class in the same package will be able to access it, but it will be private outside the class.
This rule is not always known, and it is a good approximation of a C++ "friend" keyword. I find it a good replacement.

- 30,874
- 30
- 96
- 127

- 583
- 1
- 6
- 18
-
1This is true, but I was really asking about code residing in different packages... – Matthew Murdoch Dec 13 '10 at 14:40
I think that friend classes in C++ are like inner-class concept in Java. Using inner-classes you can actually define an enclosing class and an enclosed one. Enclosed class has full access to the public and private members of it's enclosing class. see the following link: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

- 57
- 5
-
Er, no, they're not. It's more like friendship in real life: It can, but doesn't need to be, mutual (A being a friend of B's doesn't mean B is considered a friend of A), and you and your friends can be from totally different families and have your own, possibly (but not necessarily) overlapping circles of friends. (Not that I'd like to see classes with lots of friends. It can be a useful feature, but should be used with caution.) – Christopher Creutzig Aug 17 '15 at 07:17
I agree that in most cases the friend keyword is unnecessary.
- Package-private (aka. default) is sufficient in most cases where you have a group of heavily intertwined classes
- For debug classes that want access to internals, I usually make the method private and access it via reflection. Speed usually isn't important here
- Sometimes, you implement a method that is a "hack" or otherwise which is subject to change. I make it public, but use @Deprecated to indicate that you shouldn't rely on this method existing.
And finally, if it really is necessary, there is the friend accessor pattern mentioned in the other answers.

- 30,874
- 30
- 96
- 127

- 114,675
- 90
- 247
- 350
If you want to access protected methods you could create a subclass of the class you want to use that exposes the methods you want to use as public (or internal to the namespace to be safer), and have an instance of that class in your class (use it as a proxy).
As far as private methods are concerned (I think) you are out of luck.

- 54,530
- 68
- 182
- 238
A method I've found for solving this problem is to create an accessor object, like so:
class Foo {
private String locked;
/* Anyone can get locked. */
public String getLocked() { return locked; }
/* This is the accessor. Anyone with a reference to this has special access. */
public class FooAccessor {
private FooAccessor (){};
public void setLocked(String locked) { Foo.this.locked = locked; }
}
private FooAccessor accessor;
/** You get an accessor by calling this method. This method can only
* be called once, so calling is like claiming ownership of the accessor. */
public FooAccessor getAccessor() {
if (accessor != null)
throw new IllegalStateException("Cannot return accessor more than once!");
return accessor = new FooAccessor();
}
}
The first code to call getAccessor()
"claims ownership" of the accessor. Usually, this is code that creates the object.
Foo bar = new Foo(); //This object is safe to share.
FooAccessor barAccessor = bar.getAccessor(); //This one is not.
This also has an advantage over C++'s friend mechanism, because it allows you to limit access on a per-instance level, as opposed to a per-class level. By controlling the accessor reference, you control access to the object. You can also create multiple accessors, and give different access to each, which allows fine-grained control over what code can access what:
class Foo {
private String secret;
private String locked;
/* Anyone can get locked. */
public String getLocked() { return locked; }
/* Normal accessor. Can write to locked, but not read secret. */
public class FooAccessor {
private FooAccessor (){};
public void setLocked(String locked) { Foo.this.locked = locked; }
}
private FooAccessor accessor;
public FooAccessor getAccessor() {
if (accessor != null)
throw new IllegalStateException("Cannot return accessor more than once!");
return accessor = new FooAccessor();
}
/* Super accessor. Allows access to secret. */
public class FooSuperAccessor {
private FooSuperAccessor (){};
public String getSecret() { return Foo.this.secret; }
}
private FooSuperAccessor superAccessor;
public FooSuperAccessor getAccessor() {
if (superAccessor != null)
throw new IllegalStateException("Cannot return accessor more than once!");
return superAccessor = new FooSuperAccessor();
}
}
Finally, if you'd like things to be a bit more organized, you can create a reference object, which holds everything together. This allows you to claim all accessors with one method call, as well as keep them together with their linked instance. Once you have the reference, you can pass the accessors out to the code that needs it:
class Foo {
private String secret;
private String locked;
public String getLocked() { return locked; }
public class FooAccessor {
private FooAccessor (){};
public void setLocked(String locked) { Foo.this.locked = locked; }
}
public class FooSuperAccessor {
private FooSuperAccessor (){};
public String getSecret() { return Foo.this.secret; }
}
public class FooReference {
public final Foo foo;
public final FooAccessor accessor;
public final FooSuperAccessor superAccessor;
private FooReference() {
this.foo = Foo.this;
this.accessor = new FooAccessor();
this.superAccessor = new FooSuperAccessor();
}
}
private FooReference reference;
/* Beware, anyone with this object has *all* the accessors! */
public FooReference getReference() {
if (reference != null)
throw new IllegalStateException("Cannot return reference more than once!");
return reference = new FooReference();
}
}
After much head-banging (not the good kind), this was my final solution, and I very much like it. It is flexible, simple to use, and allows very good control over class access. (The with reference only access is very useful.) If you use protected instead of private for the accessors/references, sub-classes of Foo can even return extended references from getReference
. It also doesn't require any reflection, so it can be used in any environment.

- 868
- 8
- 14
I prefer delegation or composition or factory class (depending upon the issue that results in this problem) to avoid making it a public class.
If it is a "interface/implementation classes in different packages" problem, then I would use a public factory class that would in the same package as the impl package and prevent the exposure of the impl class.
If it is a "I hate to make this class/method public just to provide this functionality for some other class in a different package" problem, then I would use a public delegate class in the same package and expose only that part of the functionality needed by the "outsider" class.
Some of these decisions are driven by the target server classloading architecture (OSGi bundle, WAR/EAR, etc.), deployment and package naming conventions. For example, the above proposed solution, 'Friend Accessor' pattern is clever for normal java applications. I wonder if it gets tricky to implement it in OSGi due to the difference in classloading style.

- 29,388
- 11
- 94
- 103
I once saw a reflection based solution that did "friend checking" at runtime using reflection and checking the call stack to see if the class calling the method was permitted to do so. Being a runtime check, it has the obvious drawback.

- 6,317
- 5
- 37
- 67
As of Java 9, modules can be used to make this a non-issue in many cases.

- 9,779
- 5
- 63
- 94
-
2This answer would be much more useful if it had pointers to explain how to use Java 9 modules for this. – DaveMan Apr 01 '22 at 20:36