I have some years experience in developing Java applications right now, but it is the first time I develop a (Java 8) library which has to be used by external developers. Thus I do not wan't to expose anything (Classes, Methods, etc.) except the API.
Thus I started implementing it in a single package and kept everything in default scope which is only internal.
Because implementing this needs many many classes which will maybe split up into more classes to ensure maintainability and testability that package becomes way to large to my mind. In a regular project I would have created plenty of subpackages to structure the code but this isn't possible because this would lead to internal classes having public scope.
Do you have any ideas or know any ways (maybe involving the build system (maven) or other suggestions when using java 8) to make such code more structured without exposing more classes as needed? It's not that I couldn't live with a single package, it just doesn't feel right somehow.
this would lead to internal classes having public scope.
Having developed such libraries for many years, this isn't as much of a problem as you might image as most developers will only use some of the documented classes and methods and don't go digging around in your code as they are aware the details might change and break their solution with an upgrade.
In short, if it's not documented, it doesn't exists for most developers.
Note: if developers wants to get into your code they can use reflection and making it private won't matter either. Or they can take a copy of the code and modify it and do whatever they like.
All you are doing is preventing developers how what to get into your code but not use reflection to do which is a small number.
Do you have any ideas or know any ways (maybe involving the build system (maven) or other suggestions) to make such code more sturctured?
Java 9's Jigsaw have greater control. It allows you to determine what will be exported outside your JAR. This way you can have
public members which can be used anywhere except from outside your JAR.