I am creating a library (android). I keeping things as packages like
com.domain.libname.datamodel; com.domain.libname.exceptions; etc.
I want the freedom of initializing some data model objects within my library which public can read, but public should not initialize those objects. Though 'package' access modifier does this within a package, i would like to do this across packages within the same project/library.
Is there a way? Or is it indicates i am not packaging things in the right manner?
The package structure in Java is flat: If you want something to be visible outside of your package it will be visible to all packages; there is no way to restrict visibility to "subpackages" or to packages with a certain prefix.
My opinion is that a package should implement a feature, so that classes that have to cooperate can do so without having to expose needless cruft to the outside. This means that you wouldn't have "artificial" packages like "datamodel" or "exceptions"; instead the data models and exceptions would be in the package that actually needs them to implement a set of use cases. But I can see how in a large application or library that can become impractical.
Related
I've run into this statement when I was reading a book on Kotlin:
With Java, the encapsulation can be easily broken, because external code can define classes in the same packages used by your
code and thus get access to your package-private declarations...
I'm not sure if I get this totally correct but does it mean can I somehow define a class in the same package with, for example, a third-party module that I depend on and then access it's package-private data? Or does it mean something else?
I have a java class containing my Database settings (username, password). I want to use this class in all the packages of my plugin but I don't want it to be available to other plugins.
How can I do that? Removing the public attribute of the class hides it from all other packages and leaving it public exposes it to all other plugins wich is bad in my case.
Isn't there some kind of keyword like protected for functions and variables?
How can I do that?
Instead of having credentials in class, create a configuration file and use it in classes where required.
If your database information is stored as plain text variables, it doesn't matter what visibility you set. Anyone interested will easily find those strings.
I'm not sure what you are plugging into, but most platforms that I have used have a way of stating which packages should be shared/hidden. This would be specific to the platform (Netbeans, Eclipse, etc...)
Aside from that, if you make your class/variables protected then only classes in the same package or which extend it would be able to use them. If no visibility modifier is set, then it defaults to package and use is restricted to classes in the same package.
Is there any way to set the method/class visibility as something like java's package visibility in vb.net?
The idea is that this method/class should be visible for classes on the same folder/package but not visible for classes outside this folder/package.
To my knowledge the closest thing to package in java in .net would be a namespace. But in .net there is no way to restrict access to types on level of namespaces if those exist in the same assembly. The only way to achieve this is to create class library and on this level you can manage visibility of classes between them by setting internal (default) or public access modifier. For more info read documentation.
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?
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.
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.
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.
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.
protected modifier can use,in case of your class will access only in same package. otherwise there is no possibility.
I always doubt when creating packages, I want to take advantage of the package limited access but at the same time I want to have similar classes divided into packages.
The problem comes when you understand that packages are not hierarchical in Java:
At first, packages appear to be
hierarchical, but they are not.
source
Imagine I have an API defined with its classes at foo.bar, only the classes the API client needs are set public. Then I have another package with some internal objects I need in the API defined at foo.bar.pojos, this classes need to be public so they can be accessed by foo.bar but this means the API client could also access them if the package foo.bar.pojos is imported.
What is the common package politic that should be followed?
I've seen two ways of doing.
The first one consists in separating the public API and internal classes into two different artefacts (jars). The documentation is separated as well, and it's thus easy for the end user to make the distinction between what is internal and what is not. But it sometimes make things more complex to have two jars, two source trees, etc.
The second one consists in delivering a single jar, but have a good documentation allowing to know what's internal and what's not. The textual documentation can explain how to use the API (and thus avoids talking about the internals). And the javadoc can specify that a class is for internal use and is thus subject to changes.
Yes, Java packages don't give you enough control over your dependencies. The classic way to deal with this is to put external APIs in one package and internal implementation classes in another, and rely on people's good sense to avoid creating dependencies on the latter.
With Maven and OSGI, you have an additional mechanism for managing dependencies between modules / bundles of packages. In the case of OSGI, you can explicitly declare some packages as not exported, and an OSGI aware development environment will prevent people creating harmful dependencies. Maven's module support is weaker, but at least it controls dependency cycles.
Finally, you could use custom PMD rules to enforce your project's modularization conventions ... in the same way that there are rules to discourage dependencies on Java's "com.sun.*" package tree.
It is a mess.
Using only what Java itself offers, you have to put everything in the same package. You end up with a single (or a few) packages with lots of classes, and no good way to group them for yourself (but at least that problem does not leak outside). Most people don't do that, though, and as a result, your (as a developer on top of these libraries) public classpath is littered with stuff you should never need to see.
You might like OSGi, which has (and enforces) the concept of bundle-private packages. Those are not exported to the outside world.