JAR-Level (Assembly-Level) Class Scoping in Java - java

In C#, if I want a class to be visible to any class within that assembly (DLL), I simply scope it as internal (which is the default).
How can I do this in Java? In Java, I've noticed the default/internal scoping is package level, not JAR level. This is a problem for me, since I have a library that has several sub-packages with different responsibilities (view, controller, etc.) and can't put them in the same package.
As an example, I have two classes like com.stackoverflow.main.first.One and com.stackoverflow.main.second.Two, both of which should be able to instantiate each other.
Edit: I don't want the class to be public and visible from anyone who references it. It's an internal class only. I'm creating an API for consumption, and of primary importance to me is which classes can be seen by consumers of my JAR.

Java has no concept of library-level scoping. Make the classes public or use a factory.

To accomplish what you want, you'll have to use some mix of a factory pattern to create the classes you want to expose and leave the private classes package private. Usually, I've done this:
create the public interface for the API in a package like com.foo.bar a la public interface Foo {}
create a factory class that exposes a create method a la:
public class FooFactory{
public Foo buildFoo(){ return new FooImpl(); }
create FooImpl as a package private class - class FooImpl implements Foo{}
Document package to indicate proper usage.
It's not perfect, but until the JSR about module scoping progresses, it's probably the closest you can get in java. If you want to ensure that FooImpl doesn't get inappropriately extended, be sure it is marked final.

sounds as simple as you have to use the public access modifier.

Related

Why cannot I use a package-private (implicit) class as the top-level class of a java file?

I am new to Java. Maybe the question is a bit naive.
For example, I have a pkg1, in which there are 2 Java files: f1.java and f2.java
As the title, I feel it is reasonable
to use a package-private-top-level class for f1,
then use a public-top-level class for f2,
then the outside of pkg1 can still access f1 via f2.
I can even have f3, f4... ..., which are all using package-private class as their top-level class. Then f2.java will become a package-interface file for the rest of files in pkg1.
So, why is the fact that a top-level class must be public? Just to prevent from unnecessary complexity?
According to Oracle Java tutorial, public isn't the only possible modifier for top-level class:
A class may be declared with the modifier public, in which case that class is visible to all classes everywhere. If a class has no modifier (the default, also known as package-private), it is visible only within its own package
So, basically, there's no problem in making some classes protected or package-private if your design requests it.
Term 'top-level class' actually exists in Java as well as terms 'inner class' and 'nested class', I suggest you to take a look on this page to clear some basics of java class hierarchy.
why is the fact that a top-level class must be public?
A "top level" class in Java is just a class that isn't a nested class (a class inside another class — JLS§8). They are not required to be public.
You may be thinking of applications that are run via the java tool (not all are!). The class meant to be used as the entry point for the java tool is usually shown as public in examples, but it isn't required to be. It is required to have a public static void main method accepting a String array, but the class itself doesn't have to be public.
A top level class should be public because a public class can be used any where in the java universe,but if you declare a class private or protected then its sole purpose is lost declaring a class private will not allow this class to be visible to any other class and marking it is protected will also do the same thing.Its always recommended to make a class default or public.

Java default access level (package private access). Why it is used for? [duplicate]

This question already has answers here:
Pros and cons of package private classes in Java?
(8 answers)
Closed 8 years ago.
Although I know how default (package) access level works in java, I can't imagine its real use in applications except for those with unique package. What do you use default access level for in business (usually multipackage) java applications?
A very common pattern for using package-private classes is to create shared implementations of interfaces or shared subclasses of common classes.
Note that the fact of sharing is important here, because inner classes provide a better alternative for hiding class / interface implementations from the caller.
Another common use is for "utility classes", when you wish to share a group of algorithms "horizontally" among different classes, without exposing these algorithms to outside users of your class library. Various argument checkers fall into this category.
I would use them when client code doesn't need to know the proper class implementing an interface and initializing it through a factory method or builder because the class by itself can be very complex to handle.
E.g.
Interface
package foo.bar;
public interface FooBarInterface {
}
Implementations of interface
package foo.bar;
class FooImpl implements FooBarInterface {
}
package foo.bar;
class BarImpl implements FooBarInterface {
}
Factory method:
package foo.bar;
public class FooBarInterfaceCreator {
public static FooBarInterface create(String param) {
//creates instance based on parameters...
}
}
Mostly I've used that access for unit tests. In which case, I've to change some of my private methods to give them package access, so as to test them. Of course your unit tests should follow same package structure as your actual code.

Non-public top level class in Java

What's the reason of making top-level class non-public in Java?
Let's say we have Foo.java, there could be
class Foo {
}
or
public class Foo {
}
I understand that there will be some class - visibility issues with the former example (probably it won't be visible from other packages). But anyway, are there any reasons why someone may want to do as in the first code sample?
UPD: What cons I see in the former solution: nobody cares that it's non-public. That class can be simply extended by some other public class in the same package later, then, non-public part of the class may bring you visibility/access issues.
Here is an example.
No one needs to know about existence of our ConcreteDocument.
DocumentIF.java
public interface DocumentIF {
}
ConcreteDocument.java
class ConcreteDocument implements DocumentIF {
}
DocumentFactory.java
public class DocumentFactory {
public DocumentIF createDocument() {
return new ConcreteDocument();
}
}
Typically, you make a class package-private because you don't want the class to be used outside the package. When a top-level class isn't public, it's private to the package.
Say you have a package with a number of classes that must communicate the same sort of data with one another. But this data structure is an implementation detail and so you don't want it being used by user code. Making the transfer class package private maintains this sort of package level encapsulation.
I understand that there will be some class - visibility issues with the former example (probably it won't be visible from other packages).
That seems to me to be reason enough to use it if you want to keep the class private to that one package.
Just noticed another use! It seems you can only have one public top-level class per code file, but any number of non-public top-level classes. Haven't verified it personally, but if true that could be quite useful to prevent cluttering your project folder and to group classes with related functionality that aren't needed outside of the package.
Classes without a public or protected modifier are only visible inside the package they reside. If you think of components and interfaces there is a reason for leaving out the public modifier. Let's say you have a public class MyCompontent that internally uses other classes, but does not want to publish those to the outside world (users of the component) it makes sense to leave out the visibility modifier.
It is considered good design to keep the visibility of a class to the most minimum required. The reasons that I can think of:
The class can easily change in the future without causing breakages in external packages as the external packages do not have access to the class. In this regard it might be even better to start off a class by making it a private inner class.
The class being package visible cannot be extended by classes in external packages. This again makes it easier for this class to change without causing breaking changes in external packages. If this class was not meant to be extended then it would be even better to make this final.
A public visible class becomes a part of the exported API of your library. If you are a library designer, it is better to keep your exported API as small as possible because you do not want to confuse your consumer with un-necessary classes/details. Item 1 would again hold good in this case.
The book "Effective Java" by Josh Bloch is an excellent reference for Idiomatic Java code and design.

How to hide the internal structure of a Java API to the rest of the world

i am developing a Java Api to do things (secret, uhhhh ;).
Is there a way to hide classes, and the internal structure of my API?
What i found until now:
Using inner classes (ugly way, i do not want to put all in on class file)
All classes in one package so that i can use the "package"-visibilty (also ugly, i need more packages)
Example:
---
package net.my.app;
//this is the Public Access
class MyPublicClass{
public void somePublicFunction(){
//access to not visibil classes
}
}
---
package net.my.app.notvisible:
//this is what i want to hide
class MyNOTPublicClass{
...
}
---
Any ideas?
Thank you!
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.
Related Questions: 1, 2, 3, and 4.
Use interfaces to define what your
app does
Create a main entry point to accesses services, returning interfaces only
I wouldn't bother about actually hiding the implementation classes. You can never really hide them in Java, and those who are technically interested might just start your app with a debugger. Just provide no public constructors, for example
Regarding this comment:
Sean, would you elaborate a little
more on your answer? ...
One way to implement my second bullet point I mean using a Service Lookup class, e.g.
public class Lookup {
private static final Foo foo = new FooImpl();
public static Foo getFoo() {
return foo;
}
}
Foo is an interface, FooImpl an implementation class (which can be package private if you want to enforce that it can't be instantiated by clients)
What do you mean by 'hide'?
You can use the final modifier to stop people from extending methods and classes you don't want them to extend. If you want to stop people from decompiling your code, you can use code obfuscation and if you want to take it even further, you can use anonymous inner classes that implement interfaces.
You can try and make only your interfaces public. Have a look at the Factory Pattern.
Alternatively, you can implement you're application in OSGI.
Neither of these methods would allow you to hide the implementation completely to someone who really wanted to see it. Someone could still use a decompiler to examine you .class files, or even examine the code in memory.
If you really need to protect your implementation in this way, then a good approach would be to only allow access to your application as a remote service and host it on a secure machine.

what is the use of having public methods when the class is having a default access modifier?

as for my observation when the class itself is having default access modifier, what is the use of having public methods in it. the java compiler could have stopped using public methods in default class. is there any reason for that?
The non-public class might implement a public interface. This would mean that classes outside of the package could not create an instance of this class or create references of that type, but they would still be able to invoke methods on it if passed an instance.
For example, a public factory class might create an instance of an non-public class in its package and return it.
One reason: if your class implements some interface (or extends some abstract class with abstract public methods), then you may not reduce the visibility of those implemented methods.
It is a beautiful combination of Security and Usability packed in one.
I would mark a Class with default access if I want it to have a, well, package access (so that no other package can use it or better change the code) and marking a method public, I am making the method accessible to all other classes regardless of the package they belong to.
How does that help? A class which is secure enough to perform all the complex code implementation and usable enough to give the output to the user who wants to use it.
How can anyone use that? Well you write code to help them use it by creating a public class which extends this default class. You Instantiate this public Subclass in any package (after importing of-course) and this has all the methods marked public.
You have a class which does your magic which everyone can use without giving anyone else a hint of how you got it done!

Categories