Yes, what you want to do is possible. You can write EJBs that are deployed to JBoss AS and then access them via JNDI from a standalone client. Do a Google search for "ejb standalone client" for examples.
However, that method is somewhat passe. You might be better off using web services (especially RESTful ones), deploy the web services to JBoss AS and have the standalone clients make web services calls. You'll also have a lot more options of the types of client you could write.
Hello Peter -
Thank you for the quick response! I confess I hadn't spent any time looking at web services, since we weren't planning on using a web client. I'll check out the RESTful services as you suggest, and (unfortunately) likely be back with more naive questions.
I am wondering about the complexity and difficulty of maintenance of this kind of setup. Given that there's only a few of us and we don't have an infinite amount of time to get all of this up and running, (and that it'll really just be me who would be maintaining it in the future), I'm a little concerned about the learning curve. Assuming a strong background in Java SE, but no experience with EJBs, web services, or getting an application server up and running, any thoughts on how long it would take to gain at least a basic familiarity with these things? (I know, it may be an un-answerable question.)
Unfortunately, if this is you first Java EE project, you will probably do it incorrectly and make a lot of mistakes. Many of those mistakes will be performance related, some will be maintaibalility and extensibility related. You usually need to try out a few sample projects to familiarize yourself with the technology, then try a few additional projects that focus in on the kinds of things you are doing, before you can really tackle your project. But of course that advice applies to anything new that you are accustomed too (ie, it is not specific to Java EE).
The question in my mind is what is the issue with the way you are doing it? And what capabilities or benefits do you think you will gain by placing an application server between the client apps and the database? With JDBC, you are essentially letting the database act as a server. And databases are very good at managing multiple clients and keeping their updates and queries straight.
Our major reason for looking into the application server setup is that we want to manage the number of available connections to the database. The problem is that the database we want the app to talk to is a general resource shared by more than just our department. Our old apps are only used by a relatively small number of people, so in creating those we didn't worry about keeping track of how many concurrent copies might be running (and hence how many concurrent connections they're generating). However, this new app will be much more widely used (in the range of 100-150 people would potentially be using it, vs the 15-20 currently), and we're concerned about potentially affecting all the other users if we don't have some middle layer regulating access for our app. (It's a big commercial system which a separate dedicated team maintains, and most people just use apps from the same vendor to interact with it - I assume those apps are connecting through some middle tier, but I don't really know, and it's all C/C++ based in any case.) It's not the transactional isolation that we're concerned with, since as you say database systems are designed to provide ways to handle concurrency issues.
A second issue which came up recently is that the commercial system was updated and the underlying database schema changed slightly. We have a bunch of small apps (again, used by only a few people) which retrieve information from it, and although most of them were communicating through a couple of base access classes, in a number of places some extra SQL queries had crept in, and we had to hunt down all of them to make sure they matched the new schema. One thing we were hoping is that by using Hibernate as an interface for the database we would avoid that kind of problem in the future.
Maybe the application server idea is overkill? Assuming we're careful with our transaction demarcations and try to optimize our SQL queries to minimize database load, could we get away with just connecting directly the way we have been? (Again, I apologize for the dumb questions! Thank you for your patience!)
If you are just trying to limit the number of concurrent database connections, then connection pooling might be a better way to go. But check the docs for your JDBC driver to see if it supports connection pooling.
An app server, such as JBoss AS, does provide such connection pooling automatically. Currently, does each app connect to the database using it own credentials, perhaps based on the user running the app? Or do all of the apps use the same credential? With an app server, you will end up with the latter. You can search through the forums for people who have had varying degrees of success with using multiple credentials.
I'm not sure if Hibernate will shelter you from the types of schema changes you mentioned. Hibernate likes to keep its information in sync with the database schema and based on a startup option might even modify the database to match what it thinks the schema should be. I am used to rebuilding a Hibernate app after making a schema change (but I don't know if htis is required). I should really let a Hibernate expert field this question for you, they could give you a better idea. (That's a hint for those of you reading along to join in the discussion...)
Okay, here is a really dumb question: to set up our own connection pooling between multiple invocations of an app in separate JVMs, wouldn't we need some middle layer to maintain the connection pool and provide a naming service so that the app can request the connection? This is what I had understood, which is why I was looking at app servers, which provide both. I'm probably missing something really obvious here. (We're using Sybase JConnect by the by, and it does indeed support connection pooling.)
As for the credentials, you're right, they do vary on an app-by-app basis (though actually not on a user-by-user basis, and there are only two sets, one for read-only apps and one with some limited write access). I was naively thinking one would do this by just setting up two different data sources, which actually access the same database but with different credentials, but I'll have to look into that further - thanks for the heads-up!
We were hoping that by using Hibernate we could enforce the use of data transfer objects that would in some measure be independent of the underlying schema, with the mappings and read/write logic specific to the schema hidden from the client apps, so that when the schema changed all we'd have to do is alter the mappings, etc. (Of course this is only for relatively small changes - I would assume that for any major restructuring all bets are off.) But I don't know how realistic that idea is, having never used Hibernate (other than building the tutorial example).
By the by, I'm not trying to be argumentative or obnoxious, and I realize I may have come across that way, for which I apologize. I've been trying to give myself a crash-course on this stuff over the last several days, and I've been concerned that I'm missing some fundamental piece of the picture. Unfortunately, my coworkers don't know any more about it than I do, so I decided to turn to the forums to try to validate my understanding of how different pieces fit together and communicate with each other. I definitely welcome anyone saying "Hey, you've got this basic idea wrong! What you're saying makes no sense!"
Oh, you are not sounding argumentative or obnoxious, I'm just really busy.
I've never set up a connection pool using just the JDBC driver, so I'm not sure how it works in practice. And the more I think about it the more I think that the pool is available only to the one app, and not across multiple apps. But then i have been wrong about stuff like this before!
The idea to set up two data sources in JBoss AS, one for each credential, would work. Your update requests would use the update data source, and reads would use the other data source.
And we are still waiting on someone with more Hibernate expertise to comment on schema changes...