Let me set up this three jar scenario in a bit more detail and assume all of this takes place in a pre JDK 9 world.
On the left the application has an API intended to be globally accessible. It is the public Foo interface in "package P".
The application also has some "helper code" which creates or assists implementations of the API,
ideally without being accessible by users of the application. It is the P helper package
package P.Helper;
Finally, on the right, the application has implementations of the API. Again intended not to be user accessible.
Those are classes X and Y which live in different jar files and implements the p.Foo API
Helper Code Implementations
In order for the helper code and the implementations to work together they need to be in the same package.
The implementations you would definitely make them "package private", so that user code cannot access them.
The helper class FooHelper is then package private as well.
It could be public, but then it will be accessible to users and we don't want that.
Challenges with this setup
There are a bunch of problems with this setup, which is really the only way you had to structure an application prior to JDK 9.
First Problem: For one thing, you have got to make sure that the implementations in the
P.Helper package do not interfere with each other.
Class Name overlaps
There cannot be any class name overlaps between the implementations, since they all contribute to the same package P.Helper, despite living in different jar files.
Second Problem: A second problem is that you cannot make effective use of sub packages.
As these implementations grow larger it will be natural for them to introduce sub-packages. But subpackages can't access the "package private code" in P.Helper.
See Oracle Packages Java 6 Packages
So you really would need a public class in P.Helper to act as a backdoor for some packages living in the implementations, but then of course anyone in the world can get to the backdoor as well.
Third problem: Third problem of course is that anyone can make a jar with classes in the
p.Helper package and start relying on the helper code in the API.jar and the details of classes X and Y in the implementation jars.
package P.Helper is being overloaded
What is really going on here is that the package P.Helper is being overloaded. It started life as a simple namespace for code that helps the API.
But now it finds itself being the unnatural home for all kinds of vaguely related things. Question: What was the developer meant to do?
In JDK 8, the only structuring mechanisms were classes, interfaces and packages.
Splitting the package across jar files was seen as acceptable, but you can see that it has a host of downsides.
In JDK 9 the structuring mechanisms are classes, interfaces, packages and modules. Modules take the strain of encapsulation and concealment so that packages can focus solely on being namespaces that are meaningful to the developer.