Really, you can't? Then I struggle to see how'll get anything else right. I've done it by using separate build scripts. That way only the interfaces and domain objects are exposed in the libraries. Now you lock down at the repository level access to each sub-project to the team working on it. There you go: modularity, boundaries, all without network hops.
sure - if you do that from the start. Most don't. The codebase organically grows and then lines are blurred and then you have to come in and refactor. When this refactor affects several teams, it gets harder in combinatorial fashion.
With an HTTP API boundary, you don't get to reach into my code - it is literally impossible.
But the work required to factor things out behind an HTTP boundary is a superset of the work required to factor things out into a module as GP describes. So if you were going to do microservices, you could do that same factoring and then just stop when you get to the part where you'd add in networking and deployment scripts.
Really, you can't? Then I struggle to see how'll get anything else right. I've done it by using separate build scripts. That way only the interfaces and domain objects are exposed in the libraries. Now you lock down at the repository level access to each sub-project to the team working on it. There you go: modularity, boundaries, all without network hops.