Most of the time you can cut out a lot of the code in those scripts and just focus on running the the main program. If you can tell it to run in the foreground instead of the background that will make things simpler. Otherwise you have to use 'expect fork' or 'expect daemon' to follow the forks that a program must do to detach from controlling terminals.
pre-start is mostly for setting things up, like creating dirs in /var/run. You can also source a config file, as the environment will be passed along to the main exec.
post-start can be helpful if you want to make sure that upstart doesn't consider the service started until a certain condition is met (like the port is answering queries).
Ultimately, the goal is to make it as simple as possible. If the startup.sh runs 'jira --daemon' and you can instead run 'jira' and it doesn't detach, then with upstart you'd just do
start on runlevel 
stop on runlevel [!2345]
As long as the process doesn't daemonize, its very easy for upstart to track what it is doing, which ultimately leads to a simpler job file and a more robust system.