How can we restrict API calls based on Applications?
Solution 1:
No, this is completely impossible. The part where you go 'I can analyse the load balance logs to see that it is a java SDK impl doing it' is based on some information that the client sends to you - probably a User-Agent:
header. This can be faked, trivially.
If you e.g. give JavaSDK requests more restrictions than, say, Chrome (the browser), then the users of your API writing in java will just sent chrome's User-Agent to you.
API restrictions are based on things that you can't fake, such as access keys. You can't make access keys that certain apps can't use - all programs are turing complete, which means they can all do what all the others can do.
Your only recourse is legal: As part of handing out an API key, the recipient signs a contract. You can stipulate in the contract that, say, you must not lie with your User-Agent.
However, whether such a contract is enforcable is dubious in the first place. "Catching" someone misusing the API (sending a user agent from a less restricted app) is difficult, and it is rather unlikely that you can stick a heavy punishment on 'getting caught' as a deterrence and make that legally stick.
In other words, effectively the answer is: Nope, you can't do that.