Adding an external class with the same package name and breaking encapsulation - java

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?

Related

How packages provide security for classes and interfaces?

While reading about packages in java i came across an imp feature of packages in
java which says
To provide security to the classes and interfaces.So that Outside persons can't
access it directly but how?
I havent used this feature and i am curious to know about it.
The question was vague, but this is a way to provide security using packages...
If a variable is protected, only subclasses of it, and classes in the same package can access it. This can be useful if you want to add security as you can only make files that you add to your package be able to access the variable in your class.
Example:
Say if I a bank program. I have a protected variable called balance. If the variable was public someone could crete a program that could access the class and change balance however they pleased. But since its protected, only the files I put in my bank package can access the variable to change it.
Packages don't provide security in any meaningful sense. However, they do help to support modularization via "package private" access:
package com.example;
public class Example {
int someMethod() { ... }
}
The access for someMethod is package private, which means that it is only visible to other classes in the com.example package. You can control the visibility of fields, classes and interfaces in the same way.
Note that this is NOT a credible security mechanism for most Java applications. It is simple for an application to use reflection to work around most (if not all) access restrictions based on access modifiers. The only way to stop that is to run untrusted code in a security sandbox that disables the use of the reflection APIs.

Library level access modifier

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.

Package and visibility

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.

Does Java provide 'friend' access modifier?

I wonder if Java provides 'friend' (as in C++) access modifier? Someone said we can tread 'friend' as default modifier in Java. Is it true?
The default access modifier in Java allows members to be accessed by any code in the same package.
There is no such keyword (in Java) named as -
“Friendly”
The default access modifier has no keyword, but it is commonly referred to as “friendly.” It means that all the other classes in the current package have access to the friendly member, but to all the classes outside of this package the member appears to be private. Since a compilation unit – a file – can belong only to a single package, all the classes within a single compilation unit are automatically friendly with each other. Thus, friendly elements are also said to have package access .
Friendly access allows you to group related classes together in a package so that they can easily interact with each other. When you put classes together in a package (thus granting mutual access to their friendly members; e.g. making them “friends”) you “own” the code in that package. It makes sense that only code that you own should have friendly access to other code that you own. You could say that friendly access gives a meaning or a reason for grouping classes together in a package. In many languages the way you organize your definitions in files can be willy-nilly, but in Java you’re compelled to organize them in a sensible fashion. In addition, you’ll probably want to exclude classes that shouldn’t have access to the classes being defined in the current package.
There isn't a friendly modifier in Java. In Java it is called package private. And it is the default modifier. It allows members of the same package to access it.
As others have said, there is no friend access, but package based access is available.
However OSGI, and the (hopefully) forthcoming Super Packages attempt to extends this concept to classes in a some higher lever grouping of classes.

Dependency Injection and Java packages

I'm doing a project that has a couple of packages. All my classes are implemented according to Dependency Injection ideias.
Now, there will be some place, in my application, that'll have the responsability of instantiating all the objects (actually I'm using an IoC Container for that, but that shouldn't matter) -- the so called Composition Root.
Now, the problem lies in the fact that, at least to my understanding, the composition root will have to know all the classes that'll be used of the system. That is, all the classes will have to be marked as public.
I could define for each package a Package Composition Root and then call each one of them from the system's composition Root but that doesn't seem that great of an idea.
In C#, for example, the situation is not so grave as there is not the package-protected access modifier -- there's internal (accessible for all the elements of the current assembly), instead.
How do you guys generally handle this?
Most containers get around access restrictions by using reflection. However this is just a hack to make you feel like you have some protection when actually relfection allows you to ignore the access modifiers.
IMHO, if you are accessing a class in another package you should be clear about this and give it an appropriate access modifier.
It sounds to me like the situation is the same in C#. If the bean factory is outside of a package, and the developer makes a class internal, does that not deny access to the bean factory?
I make the classes public and don't worry so much about it.
The interfaces that clients should be using are public by definition. Since they don't instantiate or use the implementations directly, there's little fear of giving them public access.
An alternative might be to create a factory method and make it available to the bean factory. Let it choose which implementation to provide for a given implementation using the public factory.
Now, the problem lies in the fact that, at least to my understanding, the composition root will have to know all the classes that'll be used of the system. That is, all the classes will have to be marked as public.
...
How do you guys generally handle this?
By marking all of the classes as public. This isn't really seen as a problem in the Java world.
This is an old question but I think is very important to still talk about that. While other guys try to say there is no problem with making classes of packages public to be accessible for composition, I disagree completely. The most import feature of a package is to hide details from the others using access modifiers. You can argue about the details word and say the main class of a package that provides its main features is not details of the package. I will answer when you use polymorphic interfaces to isolate your package from outside world, that main class is also part of details. Restricting access to that main class is useful when you want to protect your software architecture from being violated by the other developers in you team by the aid of language features at compile time. If you do not have such a feature in Python, I feel sorry for you but it doesn't mean there is no need to use such a great feature in Java, C#, etc.
Suppose you have a package that communicate with the outside world using a polymorphic interface and all of its internal types are access-restricted. So how the main class that implements that interface can be initialized in the composition phase while composition operation is happening out of all packages? This is the main question.
As Devoured also mentioned himself, there is no way except defining a public composer in each package that instantiates and composes all internal types and finally returns an object of the type of the polymorphic interface that isolates this module from the outside world.

Categories

Resources