Is it safe to run a database connection pool (like Commons DBCP or c3p0) as part of an application deployed to an application server like Glassfish or Websphere? Are there any additional steps over a standalone application that should be taken to ensure safety or performance?
Update, clarification of reason - the use case I have in mind could need new data sources to be defined at runtime by skilled end users - changing the data sources is part of the application's functionality, if you like. I don't think I can create abnd use container-managed pools on the fly?
AFAIK it works, but it will of course escape the app. server management features.
Also, I'm not entirely sure how undeployment or redeployment happens and whether the connections are correctly disposed. But that can be considered as a minor safety detail: if disposed improperly, connections will simply time out I guess. I'm also not entirely sure whether it works for XA data source which integrates with the distributed transaction manager.
That said, using the app. server pool is usually a matter of configuring the JNDI name in a configuration file. Then you get monitoring, configuration from the admin console, load management, etc. for free.
In fact, you can create container-managed datasources depending on AS you use.
For example, Weblogic has an extensive management API that is used, for example, by their own WLST (Weblogic Shell) to configure servers by scripts. This is, of course, Java API. It has methods to create and configure datasources too.
Another route is JMX-based configuration. All modern AS expose themselves as JMX containers. You can create datasources via JMX too.
All you need is to grant your application admin privileges (i.e. provide with username/password).
The benefit of container-managed DS is it can be clustered. Also, it can be managed by human being using standard AS UI.
If that doesn't work for you, why, sure you can create application-managed DS any time and in any numbers. Just keep in mind that it will be bound to a specific managed server (unless you implement a manual clustering of it's definition).
I don't see why you'd want to. Why not use the connection pool that the app server provides for you?
Update: I don't believe it's possible to create new pools on the fly without having to bounce the app server, but I could be wrong. If that's correct, I don't believe that Commons DBCP or C3P0 will help.
Related
I have developed a Rest webservice using JERSEY. WIth connects with the oracle database. I have JDBC connection code in my code itself, like the url, IP and username and password. Is is really required to again to configure the database connection on the server? like giving a JNDI name etc. Please help.
Thanks in advance.
Is it really required to again configure
No. It is not required to configure the database on the server, giving it a JNDI name and so forth.
Having said that, JavaEE best practices call for design whereby an application doesn't know the specifics of how to connect to external resources (such as databases). Instead, the application should "look up" that external resource by a logical name, and receives an object through which data can be accessed.
The main benefit in that is that your application code can focus on application functionality, while the application serving environment can take care of low-level aspects such as connection pooling, statement caching and so forth.
The other benefit of following this paradigm is that your application becomes immune to changes in the location of the database: no need to recompile your code, or re-package your application, in order to refer to a different data source. Instead, you could change the data source definition in the application serving environment so it points to a different location, and you're good to go.
Everyone seems to say that you should use Tomcat's JNDI contexts to manage your JDBC connections and drivers and so forth. And after reading over the documentation, I understand the draw. But if you use it, your application must use a Tomcat container from now until the end of time. Isn't it a bad programming practice to make your application rely on such an environment configuration (especially for Java, which is supposed to be "Write Once, Run Anywhere")? How is this not a dangerous development decision?
Isn't it a bad programming practice to make your application rely on
such an environment configuration (especially for Java, which is
supposed to be "Write Once, Run Anywhere")?
Yes, in general. However, this design provides several benefits, including managed connection pooling and abstracting the database connection configuration from your application. JNDI itself is a directory service abstraction which protects you from directory API differences.
How is this not a dangerous development decision?
Using JNDI to manage JDBC connections is not specific to Tomcat. Every Java application server (GlassFish, Oracle, WebSphere, etc.) does this. So you're not tying yourself to Tomcat, just to Java.
See also: Using JNDI for Database connections
I don't know which documentation you read, but if you use JNDI, the only thing which you specify in the application, is the JNDI name of the resource you want to use (e.g. for the DB connection). Everything else is configured in the container and not part of your application (like URL of the DB, username, password etc.).
I'm new to java in web application design and I'm getting surprised how many things I don't now.
In particular I'm having problems in understending how servlet containers manage resources like connection pooling classes.
Assuming that I choose a pooling library (let's say c3p0), I read that there are many ways to use and manage the connection pooling classes.
For instance in many examples I saw that a certain class (let's say ComboPooledDataSource) is instantiated in the init() method of the servlet and here I'm getting a bit confusing. I mean, I think that a connection pooling system must exist and have a separate life with respect to all the servlets that will need a connection, otherwise it make no sense. So I think that the class below may be a Thread that is started once from the first servlet that call the init method and then it continues to exist until someone doesn not interrupt it. Is that correct? If not how does it work?
Anyway once I start this class , is it shared among all the servlets in the context (I mean all the servlets that call it in the init method)?
Other examples set up the connection pooling system as a resource by for instance defining it in the context.xml and then any servlet that want a connection just have to access it via JNDI (JNDI is correct?). What i understood (or I think to) is that in this case the thread that will execute the pooling system is started when the application is started and each servlet can access it when it wants to. Is that correct?
In this case can I modify the connection pooling system properties by a servlet or a background thread runtime? (for example if I want to change the number of connections as a function of the statistics on the number of requests and so on)
If I want to create different pools (for example I want to subdivide the database access to N different databases or I want to access using different usernames ) do I need to create as many resources as are the different kind of connection I want?
Is there a "better" way among these two or they are equivalent?
It comes down to ease of use of the webapp and (Tomcat) server maintenance.
You describe 2 use cases:
a connection pool used by one webapp
a connection pool shared between webapps
The first case is suitable for "ease of use": you can drop the war-file in any Tomcat server and it will work (e.g. Jenkins delivers such a war-file) since the webapp contains all the code needed to access a database. No need to change the configuration of the Tomcat server and restart it.
If I can, I like to deliver these kind of war-files since less things can go wrong (e.g. no clashes with configuration for other webapps). You can take it a step further by delivering Tomcat embedded with an application (so you don't need a Tomcat server to start with, an example project is here).
Note that opening a database connection pool (preferably via ServletContextListener.contextInitialized, not a servlet) and closing it (via contextDestroyed) does not involve starting and stopping a thread. The pool implementation may decide to start a background thread (e.g. to remove idle and/or abandoned connections), but it does not have to.
The second case is suitable for several webapps that share a common ground. For example, if several webapps all running in the same Tomcat server all use the same database, it saves time and effort if the Tomcat server already has a connection pool available for the different webapps (via JNDI). The Tomcat server can contain the JDBC driver software and connection pool software in the "lib" directory and configuration is done once in the context.xml of the server. If the database changes or different (patched) software components are required, only the tomcat server needs to be updated and all the webapps can remain the same. In this case, updating the Tomcat server instead of each webapp is a lot easier.
The second case is also more suitable for monitoring: there is a good chance you can monitor the connection pool via JMX. This kind of monitoring may not be available in the first case.
Changing "the number of connections as a function of the statistics on the number of requests " is not needed with connection pools: you set a maximum amount of connections to use and a timeout to remove idle connections. The connection pool will then grow and shrink with the number of requests.
Subdividing the database access to N different databases would require a different connection pool for each database, unless this is "read-only" in which case you could also use a load-balancer.
Access using different usernames is a bit tricky. I read in another question (which I cannot find anymore, sorry) that you can change the schema during runtime, but changing username/password might require a new connection in which case connection pooling is out.
Are you using Tomcat to run your servlets? Tomcat 7 has a new pooling solution that you could investigate. Tomcat also includes the dbcp libraries you can use them by setting the factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory". The DBCP pools are self managed and you can define the configuration values in the context.xml file I am not aware of how to change these values on the fly. I believe the Tomcat 7 pool use the same configuration as the DBCP with a couple of added options to make the conversion between the two simple. We use DBCP in all our applications and have not experienced problems so I have not used the Tomcat 7 pooling. I am thinking you would need to create many pools to handle most of your requirements.
I am working on a desktop Java application that is supposed to connect to an Oracle database via a proxy which can be a Servlet or an EJB or something else that you can suggest.
My question is that what architecture should be used?
Simple Servlets as proxy between client and database, that connects to the database and sends results back to the client.
An enterprise application with EJBs and remote interfaces to access the database
Any other options that I haven't thought of.
Thanks
Depending on how scalable you want the solution to be, you can make a choice.
EJB (3) can make a good choice but then you need a full blown app server.
You can connect directly using jdbc but that will expose url of db (expose as in every client desktop app will make a connection to the DB. you can not pool, and lose lot of flexibilities). I would not recommend going this path unless your app is really a simple one.
You can create a servlet to act as proxy but its tedious and not as scalable. You will have to write lot of code at both ends
What i would recommend is creating a REST based service that performs desired operations on the DB and consume this in your desktop app.
Start off simple. I would begin with a simple servlet/JDBC-based solution and get the system working end-to-end. From that point, consider:
do you want to make use of conenction pooling (most likely). Consider C3P0 / Apache DBCP
do you want to embrace a framework like Spring ? You can migrate to this gradually, and start with using the servlet MVC capabilities, IoC etc. and use more complex solutions as you require
Do you want to use an ORM ? Do you have complex object graphs that you're persisting/querying, and will an ORM simplify your development ?
If you do decide to take this approach, make sure your architecture is well-layered, so you can swap out (say) raw JDBC in favour of an ORM, and that your development is test-driven, such that you have sufficient test cases to confirm that your solution works whilst you're performing the above migrations.
Note that you may never finalise on a solution. As your requirements change, and your application scales, you'll likely want to swap in/out the technology most suitable for your current requirements. Consequently the architecture of your app is more important than the particular toolset that you choose.
Direct usage of JDBC through some ORM (Hibernate for example) ?
If you're developing a stand-alone application, better keep it simple. In order to use ORM or other frameworks you don't need a J2EE App Server (and all the complexity it takes with it).
If you need to exchange huge amounts of data between the DB and the application, just forget about EJBs, Servlets and Web Services, and just go with Hibernate (or directly with plain old JDBC).
A REST based Web Services solution may be good, as long as you don't have complex data, and high numbers (try to profile how long does it takes to actually unmarshal SOAP messages back and to java objects).
I have had a great deal of success with using Spring-remoting and a servlet based approach. This is a great setup for development as well, since you can easily test your code without deploying to an web container.
You start by defining a service interface to retrieve/store your data (POJO's).
Create the implementation, which can use ORM, straight JDBC or some pooling library (container provided or 3rd party). This is irrelevant to the remote deployment.
Develop your application which uses this service directly (no deployment to a server).
When you are satisfied with everything, wrap your implementation in a war and deploy with the Spring DispatcherServlet. If you use maven, it can be done via the war plugin
Configure the desktop to use the service via Spring remoting.
I have found the ability to easily develop the code by running the service as part of the application to be a huge advantage over developing/debugging something running on a server. I have used this approach both with and without an EJB, although the EJB was still accessed via the servlet in our particular case. Only service to service calls used the EJB directly (also using Spring remoting).
I decided that it is time for me to dig into the whole Java EE stuff. I am using EE some techniques whithin Java SE like JPA or JMS, but i still messing around with Java SE and i believe Java EE and an application server will solve some of my problems i have.
BUT: I have still some questions after reading some articles on the web.
1st: Am i limited to request-response applications? I have an application which serves XML documents via HTTP. All delivered objects are added to a queue which will be dispatched in a different thread. Some validation is made for this objectes, including the opening of sockets to a remote machine (I heard EJ-Beans are not allowed to do this, is this true?). So, is is possible to do this within an application server?
2nd: I know there are Message driven beans, is it possible to send JMS messages to a MDB from outside of the application server? I have a service which sends JMS messages, but runs, as a legacy system, not inside the same application server.
3rd: How can the System Adminstrator or User configure my application? I know that some things like database connections are configured within the application server and my application can lookup them via JNDI or get them via DI. But what about application specific configuration?
Yeah, these are quite noobish questions, but maybe someone has the time to explain me how all this stuff is working. :)
regards,
Posix
PS:
4th: It seems EJBs are not allowed to do anything with files, so Java EE seems to be no option for a Service which receives Files, pushes them around to different systems and want them to write to a Socket (see question 1)?
I can say that Java EE can be used without any doubts in your case. Let me drill a little bit more into your specific questions:
You can open socket connection from your EJB. There is nothing that prevents you from doing that. However this kind of operation is not advised for Java EE applications. In my opinion the better option is to implement Java EE Connector (JCA) that would manage pool of socket connections to your proprietary system. This is the model way to implement such a integration as per specification.
Yes! It is perfectly possible to receive messages send from external application/system (outside the AS). This is main idea of integration using messaging :) In many cases your application being Java EE application receives messages via MDB from JMS channel, but JMS is only an API and can be implemented by any messaging system e.g. IBM MQ. In this architecture the external system puts an MQ message onto the queue and your Java EE application that listens to the very queue receives the message via JMS API!
Generally speaking Application Server gives the Administrator great tools to manage Java EE resources i.e. data sources, JMS connection factories, JMS destinations, JTA transaction manager, etc. If you require the ability to change your specific Java EE application the best options seems to be JMX. Just implement a few MBeans, export those to the JMX server embedded within your Application Server and you are done. This task is really trivial in, say, JBoss, but most of the modern Application Servers offer extensive JMX capabilities these days.
For the first glance, EJB doesn't seem to be the best for dealing with files. But remember that implementation of your EJBs is still written in pure Java, so nothing prevents you from reading/streaming files and so on. I have experience with large Java EE applications that are handling large files as input files and can assure you that Java EE is is a good technology choice :)
Here are the restrictions on EJB 1.1 spec.
Here's my take on your questions:
I believe an EJB can open a socket on a remote machine, but I would say that opening sockets is too low level an operation. I'd think about exposing whatever that socket is doing for you as another EJB.
An MDB is just a listener that's registered with a particular topic or queue. It doesn't say anything about sending. If your client knows how to get a message to the queue it's possible. They just have to know the queue URL and be able to create a connection.
The admin sets up connection pools, JNDI names, etc. - everything. They do it using the admin console for the app server.
It's a violation of the EE spec to do anything with files (to ensure that an EE app is portable and distributable). However since it's all just plain Java code, yopu can choose to do anything that you want. As long as you know how your target environment looks (eg the system is for internal use) I wouldn't hesitate modifying files just because the spec says so.
In an application server like Tomcat (others too, probably, but I've never worked with them) you can not only execute things upon receiving a request, but also do things (including starting long running threads) on server startup. Basically you can do anything that you can with "normal" Java. In fact, you could put a normal Java app in application server if you just include a piece of code which calls the appropriate main() on server startup.
I would suggest applying each technology to the appropriate points where you are currently feeling pain. Regarding your specific points,
In an EE context, you would add the messages to a JMS queue, that has MDBs which would do the actual processing. Regarding the management of the HTTP request/response lifecycle, you would manage this the same way you do now, or use an existing library to do if for you. By moving to an EE app server, you would allow the app server to manage the threading, transactions, etc. instead of having to manage it manually.
As duffymo stated, MDBs are responsible for receiving messages, they do not care where the message originated from.
The system administrator can configure the app server as duffymo stated. Additionally, you can expose JMX beans to other systems or to the end user to allow them to configure services if you so desire.