You could perform callouts from Salesforce to your separate Java code (as long as it's exposed as webservice or at least can accept HTTP message).
- Read about Integration on the Force.com platform, there are many possibilities and examples.
- In the API documentation most of the time there are Java code snippets listed, for example for creation of new records (scroll down to the middle of the page, "#" anchors seem to be brokes so I cannot give a direct link).
Generally you can both "push" (send from Salesforce notifications when something happens, synchronously or not) and "pull" data (periodically ask from your Java application for changes or send INSERTS etc. whenever something happens on your side).
But if you want to run your Java on Salesforce server and not on your own machine - tough, vmforce might be the only option. I haven't tried this one yet.
In the end under the Apex, Visualforce etc. there are Oracle databases and Java (with JSP), but I doubt they'll grant access to it ;)