Execute code on JBoss after start - java

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.

Related

Spring #Transactional not working in ApplicationServer

We have a Spring-Boot application exposing some REST endpoints. We allow for this application to be operated standalone (as executable jar) or as a war to be deployed in a wildfly-11 application-server.
The class defining the REST-endpoints is marked #RestController #Transactional(REQUIRES_NEW) (both on class level, obviously). When running standalone, everything works as expected but when deployed in wildfly, the rollback on exceptions does not work. We established this by sending the exact same REST-message while operating on the exact same database.
We have confirmed via debugging that the final frames of the stacktrace is identical in both cases and especially in both cases we see a transactional-proxy around our REST-controller bean.
One difference would be, that within wildfly the application will use a jndi-datasource, prepared by wildfly while standalone the spring-boot will manage the database-connections.
Any idea what is wrong here?
Edit
I just tried explicitly invoking setRollbackOnly on the JtaTransactionmanager from within my code. The transaction will still commit. This sort of looks like a bug in Spring Boot to me.
Edit 2
Debugging further reveals that the transaction seems to be set to autocommit - every statement is immediately written to the database. This seems to be in violation to the annotation #Transactional and also to the fact that Spring creates a transactional proxy around my bean.
It's not a full answer - just a reasoning. JNDI is usally used at the app server layer whereas JDBC - at the application layer. At the App server layer are used global transaction settins that are overriding app settings. Follow the spring doc to get more
For reasons beyond my understanding the default transactional behaviour when deploying a spring-boot webapp to an application-server is auto-commit.
The solution to this problem is to enrich your application-configuration with the property spring.datasource.tomcat.default-auto-commit=false

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.

Apply around advice to existing EJB

We have a third party application deployed on JBoss and Weblogic. We need to log access to EJBs in this application for audit purposes. Is it possible to apply a transparent service that will log all calls to these EJBs to a file or database ?
The only option that I can think of is to use Spring as a business delegate and modify clients to use the Spring bean. Unfortunately, we do not have an option of modifying client code and this has to be done on the server in a way that our code gets executed before and after EJBs are invoked by clients.
I searched for a solution for this and have found nothing that could point me the right direction.
Thank you for the help.
Edit:
After further research, it appears that JBoss does support custom EJB interceptors. Configuration for this is possible using standardjboss.xml for EJB 2.x and ejb3-interceptors-aop.xml for EJB 3.x
As it turns out, there is not much available by way of samples on how to create such interceptors for use with EJB 2.x - which is what I need. It does not appear too difficult and I will try this to see if it works.
You should be able to just use straight forward EJB 3 interceptors. Look for DefaultInterceptor in http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/EJB3_Interceptors.html to see how to apply an interceptor to all ejbs in your deployment. This is supported by the EJB 3 spec.
For EJB 2.x in JBoss, take a look at standard-jboss.xml. There you can either modify the full default containers for the different ejb types. You can also create a new container configuration in standard-jboss.xml and add your interceptors there and associate your EJBs with the new configuration by including a jboss.xml in your ejb.jar META-INF/ folder. Or, if I remember correctly, you can both define the new container configuration and the association in META-INF/jboss.xml. Some information here: http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/EJBDeployer_MBean-Container_configuration_information.html

Initializing Memcached/JDBC Resources for a JAX-RS servlet

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.

DI in an EJB/MDB Application

I'm currently developing a small EJB application running on IBM Websphere Application Server 7 (Java EE 5). The app mainly consists of one MDB listening for incoming MQ messages which are transformed and stored in a DB. Currently I'm using a lot of Singleton/Factories to share configurations, mappings, datasource lookups etc. But this actually leads to some very hard to test code. The solution might be using a (simple) DI framework like guice/spring to inject the different instances. The question is: Where to place the initialization/ setup code? Where is the main entry point of the application? How can I inject instances into the MDBs?
it might be worth looking at backing off from using Guice, and trying to work with the injection mechanisms already available with Java EE 5.
Regarding finding a suitable "startup point", unfortunately the EJB specification does not define a way where you can have a bean run at startup. However, the web profile of the EE spec does have one -- you can add a WAR to your application, and set a servlet listener component:
http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletContextListener.html
You can set this to start whenever the application is loaded and started by the container (WebSphere). Watch out for classloader issues though.
Using Spring, you can do it via EJB3 interceptors, see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ejb.html#ejb-implementation-ejb3
Useful info on caveats are in the javadoc, make sure you read it: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/ejb/interceptor/SpringBeanAutowiringInterceptor.html

Categories

Resources