Initializing Memcached/JDBC Resources for a JAX-RS servlet - java

I have a service where I want to maintain data persistence in a mysql db using jdbc. While i have experience building jdbc apps and jax-rs apps in isolation, I've never combined the two. The question is, where does the build up and tear down required for the jdbc-type stuff go? Ordinarily i'd put the build up in a static block, or in a constructor, and id have have a cleanup method that gets called in a finally. this doesnt seem to work in the jax-rs framework- the constructor gets called at every invocation, and there is no place to my knowledge to put any clean up methods. unfortunately, there are sparse examples for combining the two technologies online, something i find surprising. Can you guys help me out?

As a general rule, to do things at the startup and shutdown of your web application, you should create custom ServletContextListeners and list them in your web.xml.
With JDBC resources in a WAR, often times you have your container (e.g. Tomcat, Websphere, etc.) create and manage a connection pool which can be shared with a number of web applications. You would define a resource-ref for a javax.sql.DataSource in your web.xml. Then there is a container specific method for defining and binding the JDBC DataSource to the resource-ref of your application.
I'm not familiar with Memchached and what is needed on startup/shutdown so this is only a guess. If you need to register/unregister with a Memcache server you might try having one or more env-entry tags defined in your web.xml which could be used by a custom ServletContextListener to do your bidding.

Related

Tomee Server and Application Resources and how to reference in JNDI or using #Resource

Tomee has several locations where Resources can be defined:
Inherited from Tomcat/Catalina
Server
${catalina_home}/conf/server.xml
${catalina_home}/conf/context.xml
Application
${catalina_home}/conf/Catalina/localhost/appcontext.xml
${webapp}/META-INF/context.xml
Introduced by Tomee
Server
${catalina_home}/conf/tomee.xml
${catalina_home}/system.properties
Application
${webapp}/WEB-INF/resources.xml
Not sure, but I assume also some per application properties.
This is all confusing to me. I simply want to install a connection pool at java:comp/env/jdbc/mydb.
There are additional several notes I want to take:
I might want to consider defining the resource server side - so passwords are not part of the deployment.
I might want to consider the choice of one connection pool instantiated per webapp deployed, or one globally connection pool shared for all webapps.
I might want to restrict a connection pool (with given username/password) for just one webapp, although not deployed with the webapp (hence the choice of conf/Catalina/localhost/appcontext.xml).
I am aware of following documentation:
Tomee Directory Structure
Tomee Application Resources
Tomee Admin/Configuration/Resources
Tomee Datasources
I did test out setting a simple resource in WEB-INF/resources.xml, and it was reachable as simply jdbc/mydb used for example in a WEB-INF/classes/META-INF/persistence.xml. I did not have the same success when defining the resource in conf/Catalina/localhost/appcontext.xml.
It also seems to me that Tomee has a special way for choosing root contexts where services and our resources are deployed. During startup I see attempts to remap some of the resources. Example output:
[...].createRecipe Creating Resource(id=webapp/jdbc/mydb)
[...].AutoConfig.processResourceRef Auto-linking resource-ref 'openejb/Resource/webapp/jdbc/mydb' in bean MyService to Resource(id=webapp/jdbc/mydb)
And from Tomee Documentation:
<Resource id="Derby Database" type="DataSource">
. . . . .
</Resource>
The global jndi name would be java:openejb/Resource/Derby Database
So how do I refer to that in a portable way?
It seems I can solve that by simply putting this in the WEB-INF/web.xml:
<resource-ref>
<res-ref-name>jdbc/mydb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
</resource-ref>
This allows me to access this in JNDI as java:comp/env/jdbc/mydb.
My apologies for inserting parts of answer here - but I am just adding info to this as I find it. Later, I will either move this into answers, or leave as is if someone finds a better satisfying answer.
I hope to understand:
What the mechanisms are for instantiating resources (when)
How they are reachable (directly through JNDI, persistence.xml, and or a #Resource tag).
Any standard practices around those resources

WebApp. Java EE. Where I should initialize my business logic?

I recently started learning java EE (jsp, servlets and some patterns for working with database like a DAO) and I dont understand where I should initialize my bussines logic? I think that create instances of it in body of do*** servlet methods is a bad practice. P.S. my app use DataSource and ConnectionPool for connection with db.
You need to specify your requirement somehow, what initialization you are looking for. Is it a EJB solution? Pure Servlet/JSP solution? etc.
Normally when deploying your application, after an invocation the application will load the required logic.
Of course you can do initialize to speed up the load, to make required code run before users enter the application etc.
In EJB we are talking about #Singleton and #Startup annotations.
For servlet you can use the annotation #WebServlet(name="startup", loadOnStartup="0"). Or put it in your web.xml. Depends how you code.
A more recommended way is to create you own listener, and override the contextInitialized and contextDestoryed methods. E.g. create db connection etc in initialized method and deregister the driver in contextdestory method. Use annotation #WebServletContextListener or add the listener to your web.xml
Also Java web server specific solutions exists, you need to check your vendor.

Possible JNDI lookups within EJB container

I'm going through the EJB 3.1 spec and am trying to grasp the different possible ways a JNDI call can be made.
You can do it using a SessionContext and an InitialContext (or a self-created context based on the Initial- or SessionContext).
Based on which you use the syntax differs, but I can't seem to find the logic behind it.
So my question is: when can I use what syntax to use JNDI calls within an EJB container environment?
The rest of this question just serves as illustration of my point.
For example, I believe this is always possible for a correctly injected sessioncontext or created initialcontext:
ctx.lookup(java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>])
ctx.lookup(java:comp/env ...)
// special ones like these
ctx.lookup("java:comp/UserTransaction");
ctx.lookup("java:comp/ORB");
Sometimes (only for session context?) this shorter version is possible:
ctx.lookup(<bean-name>);
What about in an embedded environment, can only global references be used?
I usually inject EJBs inside EJB container with #EJB annotation. So the JDNI look ups are done by the server at deploy time.
For example JBOSS deployment:
INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-2) JNDI bindings for session bean named TestBean in deployment unit subdeployment "MyEJB.jar" of deployment "MyProject.ear" are as follows:
java:global/MyProject/MyEJB/TestBean!my.project.TestBean
java:app/MyEJB/TestEJB!my.project.TestBean
java:module/TestEJB!my.project.TestBean
java:global/MyProject/MyEJB/TestEJB
java:app/MyEJB/TestBean
java:module/TestBean
Some are per EJB specification some are application server dependent.
If you have to make look ups from context I think the best way is to use java:global.
You can also find some additional info at: http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#POJOLocalEJB
jndi is a bit like a file system. You can refer to things using a relative path based on where you are in the tree (where you "cd"-ed to).
The injected session context is by default "positioned" on java:comp, so there you reference things that are available in java:comp, without the need to provide the "full path".
Note that java:comp itself is relative to a single EJB bean, or because of historical reasons to the entire Web module.
I'm not 100% sure what you mean with embedded environment, but if the code from which you are doing the JNDI lookup is not part of any of the predefined scopes (like java:module, java:app, etc) only java:global can be portably used.

Tomcat JNDI Bean

I'd like to know if is possible to store an object with data into a JNDI resource, like we can do in sessions, to share the data (login data) between different applications. I've read the doc in http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html but I'm still a bit confused due to the instantiation process of the JNDI. Thanks!
Tomcat's JNDI service is very lightweight, and intentionally provides isolation between webapps. The implementation also does not support remote connections and references, etc. So you won’t be able to share data between servers in a cluster.
If you don't want to use a fully-featured Jakarta EE container (like Eclipse Glassfish or Wildfly) then you might want to look into something like webcache to share data like this.

Execute code on JBoss after start

I need to execute some code after the start of the application server (JBoss).
I googled the annotations #startup and #create that might prove useful, but in this situation seems impossibile to operate with EntityManager or Hibernate current session (if using Hibernate).
Is there any chance to perform Hibernate operation immediately after JBoss is started?
Are you using a framework? If not, you could use a startup servlet. In your web.xml, simply mark the servlet to have a <load-on-startup> value and it will run when the webapp is started. If you want it to load after other servlets, just set the load order.
If you are using a framework, it will have its own methodologies, such as Spring's InitializingBean interface.
You could deploy a custom JBoss service or just use plain old portable ServletListener in a war.

Categories

Resources