Simplicity in terms of implementation. In java, all you need is Maven. There is no need for any RPC serialiser or RPC middleware.
Simplicity in terms of deployment. You will need less applications than the RPC approach. Each application requires investment of auto-deployment, monitoring, hardware resources, and load balancing in some cases. Less applications, less SiteOps burden.
High availability. The "service provider" will never be down since you have embedded it.
Performance of invocation. No time is wasted on network communication.
Cons of Library Dependency:
Performance as far as database pooling is concerned. Say a "service provider" talks to a database with 10 connections in the pool. 10 consumers embedding this service library will have 100 connections in total for the database. The load of the db server can be huge. There will be no such problem if the service provider is a standalone application, since it is only this provider application that can talk to its related database.
High coupling regarding private API calling. If no limit is enforced, a service consumer can call aprovider’s private API, that is, methods that the consumers are not supposed to call. You can introduce limitations simply by declaring rules, but it is not 100% safe. People may break it.
Indirect dependency version conflict. C relies on S1 which relies on COM_version_1.1, and C also relies on S2 which relies on COM_version_1.2. C will then have to decide which version of COM it should rely on. In Java, you may have to do a lot of Maven arbitration work. And believe me, the story can be huge.
Implicit dependency. Normally there is no service governance and I don’t know who relies on me. If I am going to upgrade my interface, I don’t know exactly which consumer systems should be involved . Maybe I can somehow find out all the consumers who relies on me directly, but it may still be hard to know who relies on me INDIRECTLY ! In RPC approach, you know who calls you if there is well governance. And you don’t need to know who indirectly calls you because it’s not your responsibility. Your direct consumers will find out and use their own discretion.
Most annoying: change in implementation of a provider leads to upgrade and redeployment of its consumer systems. Let’s say you fixed a bug in the provider’s implementation. Interface is not changed, but the consumers still need to upgrade their dependency on you! How annoying? This normally leads to a very long release process, because a lot of systems need to be upgraded instead of just one.