log4j2 logging of code in EJB jar on JBoss EAP 7 - ejb

I am doing the following:
porting several legacy applications from WebLogic to JBoss EAP 7. Some of the components being ported are EJBs. Others are servlet apps that invoke these EJBs. These EJBs are deployed in ejb-jars. I know that I could wrap this whole thing into a big EAR file but we don't want to do that. The servlets and the EJB jars need to be separately deployable components.
Then there is the logging setup. We are using log4j2 and we want to keep independent of the JBoss logging setup. I have created a JBoss module that contains all the log4j2 jars with the proper dependencies, and logging works.
The servlet runs and logs, invokes the EJBs and they work.
The only problem is how to configure the EJB's logging. In a Web App like the servlet, it's easy, just specify the log4j logging configuration file in web.xml. What's the analog for an ejb jar? I couldn't think of a way.
I tried the following: Add a logger/appender to the configuration of the servlet app for the EJB package and specify a new file. It doesn't work. The new logfile does get created but nothing gets written to the logfile. There should be output, but there isn't, so evidently when the EJB runs, its LogManager is not using the configuration specified in the servlet.
What is the right way for specifying a log4j2 configuration in an EJB deployed in an EJB jar on JBoss EAP7?

I had previously posted in this space a solution involving use of the #postConstruct and #preDestroy methods to initialize and shut down LoggerContext objects.
This plan fell apart when I tried to extend it to stateless session beans. It worked okay for Stateful Beans. Or so I thought. Eventually I found an Oracle document on EJB Restrictions which exposed the weaknesses in what I was doing. My "solution" included a non-final static LoggerContext member of the EJB class. I found a way to make it final, which did allow the stateless case to work. But I was increasingly dissatisfied with my approach. Even in the stateful case, I found issues that might bite me later in a clustered environment.
What I now come to believe is that I should not do what I was trying to do.
I can't even imagine the complexity of what a static final LoggerContext would look like if an EJB were distributed to another machine in the cluster. Objects like LoggerContext don't belong as members, static or not, of container-managed objects like EJBs.
It's not even clear that EJBs are the right implementation technology for what I am trying to build. My use cases are not really transactional so the case for EJB implementation is not strong so one possible path leads away from EJBs altogether.
The real message is that if EJBs or other container-managed components are indicated, it's probably best to use the container-provided logging system. I like log4j2, but until JBoss supports it, it's best to stick with container-provided log4j1 or some other framework.

Related

Websphere 8.5 overlapping jars between project and default server jars

I have a project deployed on websphere 8.5. However, there are certain classes that are creating conflict due to jar version errors in project and the ones provided by websphere default.
Can anyone help to point mechanism to resolve conflict.
I have done something similar in weblogic which provides option in welogic.xml to exclude / include jars from project.
This is the use case for the "isolated shared libraries" feature in the WebSphere server. For any technologies for which you need to bring your own version rather than use the version provided with the server, place the necessary jars into some directory outside the application, create a shared library pointing to that location, select the "use an isolated class loader" option in the library configuration, and associate the library with the application(s) that require it. The application will search the isolated library class loader before delegating to its parent loaders, and classes there will be found instead of server-provided versions.
A few cautions: This should ONLY be used for technologies that you are 100% certain that you need your own version rather than the server's. The "parent last" style of class loading used by isolated shared libraries includes some risk of conflicts between class loaders, and avoiding it (by using APIs provided by the server) is generally the safer option.
Note, too, that not everything can be overridden. The Servlet, EJB, and JPA APIs, for example, will break application startup if included in an isolated shared library, because the server containers require consistent versions of the API classes when processing application objects. Also, you cannot bring an API of any technology without an associated implementation - doing that is usually a recipe for a VerifyError or LinkageError caused by duplicate visibility to multiple versions of the API.

jax-rs url inside an ejb module

I created a tutorial that incorporates various components of J2EE in them. The app is an ear module that has an ejb project and a web project.
the project structure is
john-app
john-ear
john-ejb
john-web
the ejb project has a couple dao that perform basic crud operations using jpa. I'm trying to learn/understand jax-rs to gain a better understanding of json and handling json objects. the project is loosly based on
this project:
http://www.developer.com/java/creating-restful-web-services-with-jax-rs.html
so, i created my BookResource here and made it a stateless ejb. i have everything compiling and deploying without any obvious errors - other parts of the app work (the jpa stuff) but i can't get the jax-rs stuff to
work. i have a couple of"Books" that I created in my database and am wanting to test this by making a rest call through the browser.
so i deploy my .ear file in wildfly (v10) with no obvious errors, I see JNDI mappings for my EJB's...etc
initially, i'd like to be able to test this through my browser, but am not certain what url to use -- the class i have extending javax.ws.rs.core.Application has an application path of /rest and my
BookResource has a path of /library, and for getting all books from the library, the sub-resource is books. I've tried every combination of the url below,
http://localhost:8080/john-[app|ear|ejb|web]/rest/library/books
all to no avail. every call results in a 404 error, and the only time i got ANYTHING is when i tried john-web combination, it threw some ugly exception in the browser. so the questions is with a rest service living inside an ejb module within an ear, what should the url be given the above information. nothing i've tried
seems to work!??
I've not included any code samples to try and keep the explanation short -- i didn't want to include every java file in my little project, but can add anything as requested.
Thanks,
JG

Deltaspike ConfigProperty working for EJB but not for simple bean in Wildfly 8.1

I am using Apache Deltaspike 1.0 to inject properties into the beans within my application. I am curious whether the observation I made indicates a bug or not. I created a simple managed bean that was annotated with #ApplicationScoped and everything worked fine. Then I activated Wildfly's sub-deployment isolation mechanism (see the relevant section in the docs). Afterwards, the properties are no longer injected.
However, if I "promote" my managed bean to an EJB with #Singleton #Startup the properties are injected again. I actually don't need most of my beans to be EJBs but I did not find any other way at the moment.
Any thoughts?
Thanks in advance
Sven
The problem is not directly related to Wildfly 8.1, but to the combination with camel-cdi. I explained it in the Wildfly forums: https://community.jboss.org/thread/242945

how to get all jndi bindings in the webSphere

I have a websphere instance with some ejb's deployed.
How can i find out all the existing JNDI bindings available as part of the websphere instance.
I'm basically validating a feature in our product which gets all the JNDI names available. I'm trying to write the code for implementing the same for my understanding instead of debugging it.
If there is an option in webSphere to get the same that will also suffice for my requirement but I will personally want to write code and try it out.
WebSphere provides the dumpNamespace utility for that. Look at WAS_HOME/bin, you should find it there.

Securing JAX-RS in a bundle

I am creating a REST service in glassfish (which uses Jersey as the JAX-RS impl.). I want to deploy my service as an OSGI bundle which works fine, I add the "Web-ContextPath:" in the manifest and then use an annotated #javax.ws.rs.ApplicationPath application object. This all makes the service usable but then, I want to use container based security. I found I can use security contrains in a web.xml and then do the user-to-role mappings in sun-web.xml. That said, a OSGI bundle does not have either.
Is there a set of annotations and or parameters to the manifest where I can specify application roles, security constrains and role-user mappings (I think the latter can just be globally configured)?
Thanks!
Here's how I would try this:
Use a library that would automatically detect OSGi services with specific annotations, and translate them to REST resources. For Jersey, you could try this: https://github.com/hstaudacher/osgi-jax-rs-connector
Use OSGi embedded application server like jetty (or tomcat) which provides the OSGi HTTP Service implementation.
Configure Jetty/Tomcat. This should be easy now as the Jetty/Tomcat bundles can pick up configurations from the configuration area.
It would also save a lot of time to use Karaf which would do all the packaging related work for you, including providing features like embedded Jetty with externalized configurations, etc. But that's totally up to you.

Resources