Thinking about this, there are several different types of obfuscation. Let's start with obfuscation of source code, which is a complete waste of time; it's hard enough to understand without that! So let's instead focus on obfuscation of the delivery package, of how the code gets delivered to the user.
Minor obfuscation exists to prevent the casual user from poking their fingers in and breaking things easily. It doesn't keep out the determined hacker, but it does have value in helping to ensure that the things you are asked to support are what you've actually delivered. The level of protection required for this sort of thing is really quite low; the delivery package merely has to not look readable and editable (without specialist tools) and that's quite good enough.
Similarly with delivering Java applications. Merely packaging the code into an executable JAR will stop the majority of foolishness, even though it's got all the force of a polite “Please Keep Off The Grass” sign in a city park.
Even when delivering C++ code, stripping the unnecessary symbols from the executable will be enough to qualify as minor obfuscation. The key is that it is awkward to read the result as a user, but not a problem to execute it as a computer.
Major obfuscation is keeping the determined and knowledgeable user out. It's also a total losing game; if a computer can execute it, a person can pick it apart and work out what it does. The closest you could get would be to make the program decrypt itself continually, transforming what it does at one time into a completely different thing that it does at another time. Creating such thing would be rather difficult and still wouldn't keep a really good hacker out (though they would be really quite cross with you by the end of it at the amount of effort required to decrypt all that self-modifying code).
It's much better to think in terms of other solutions. For example, you could keep the “crown jewels” of the code on servers that you control and only permit service calls to it, making the client an essentially free giveaway that is a front-end to the valuable bits. Or you could go the more contract/legal route, and only hand over executables to organisations that formally agree to not poke around inside your code or compensate you if they do so (so that'd be some sort of NDA). The aim would be to create a strong incentive for the hacker to not hack, and for the users to keep the code away from any hackers not bound by the agreement.
But you must not assume that your code can never be cracked. With virtualisation, any program state of an execution can be examined and tracked, and anything that tries to defeat that (e.g., clock tracking to an external time source) will be much more likely to cause problems for legitimate users than hackers. (See the history of DRM for how even very determined publishers of information can't keep their systems secure once the code is in the hands of their opponents.) It's much better to focus on actually making legit users happy. The losses from the occasional crack will be as nothing compared to the extra money brought in through satisfying customers properly.