EJB3.1 classpath issue - glassfish-3

I have 2 POJOs, in which one of them is an EJB and the other is a helper class.
//EJB Bean class
#Singleton
#LocalBean
#Startup
public class EJBBean{
#PostConstruct
public void init(){
HelperClass helper = new HelperClass();
helper.init();
}
}
//Helper class
public class HelperClass{
private static Log LOG = LogFactory.getLog("HelperClass");
private static Long currentTime = new Date().getTime();
public void init(){
//Some statements that use Log and do other Initialization
}
}
When I deploy this EJB jar I am getting an error
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
I have the commons-logging-1.1.1.jar in the classpath; also, I have configured it to use Log4J. As a standalone app that is without EJB meta-data it works fine. Am I missing some EJB config?
BTW I am pretty new to EJB. I am using GlassFish 3.1, Eclipse Helios as IDE and EJB3.1.

This could be because you put the commons-logging-1.1.1.jar into the wrong directory or because your server already provides server-wide library which consists of logging classes.
By the way - I remember a lot of strange 'NoClassDefFoundError' because of mixing commons-logging, log4j and slf4j (especially in mismatching versions).

Related

call Remote EJB from client JAVA

I have to implement two simples java projects ; the first is an EJB projectwho contains a simple service which implement a remote interface, and the second project is a java client which try to call this ejb project ,
so here is what I did until now :
Context context = new InitialContext(jndiProperties);
TestServiceRemote proxy = (TestServiceRemote) context
.lookup("java:global/testEJB/TestService!services.TestServiceRemote");
System.out.println(proxy.showHello());
and this my ejb service :
#Stateless
public class TestService implements TestServiceRemote {
public TestService() {
}
#Override
public String showHello() {
return "Hello";
}
}
finally this my Remote interface :
#Remote
public interface TestServiceRemote {
public String showHello();
}
I had deployed the EJB in WIldfly 9 , but when I launch the java client i get this error shown in console :
Exception in thread "main" javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at swing.testClient.main(testClient.java:22)
Can someone tell me what I had wrong in my code ?
The java: namespace is not available by default in Java. You can either package your main class as an application client JAR inside an EAR and run it using an application client container launcher, or you can configure the InitialContext to have access to the java: namespace as described in this blog post.

what is the equivalence of contextDestroyed() in ServletContainerInitializer?

I have to create a class that implements ServletContextListener to add an event during the initialization or the shutdown of Tomcat. However, the class has to be located in a jar file inside WEB-INF/lib. After doing some readings, I found out that this is not possible, and the alternative is to use ServletContainerInitializer. However, only onStartup() method is available.
Is there any other alternatives where I can also add an event during the shutdown or destruction of the web application?
I am using Tomcat 8 and Java 8 btw.
Let your ServletContainerInitializer programmatically add a ServletContextListener which in turn does the desired job in its contextDestroyed().
servletContext.addListener(YourServletContextListener.class);
Not sure how you tested your code. But this the ServletContextListener works fine for me on Tomcat 8.5.5. Just try this code, no need to put this to separate JAR file.
#WebListener
public class AppContextListener implements ServletContextListener{
Logger log = LoggerFactory.getLogger(AppContextListener.class);
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
}
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
log.info("### Context is destroyed ###");
}
}

Run a code when the war is deployed [duplicate]

I need to get some configuration and connect to external resources/objects/systems somewhere and store it in application scope.
I can see two ways to setup my application:
Overriding the init() in the existing servlets and required code there and keeping all constructed objects inside that same servlet.
Having some kind of an initialisation servlet and using its init() to do the work. Then storing created objects in ServletContext to share it with my other servlets.
Which out of above is better approach? Is there any better way to share objects between servlets? Calling them directly from one another or so...?
None of both is the better approach. Servlets are intended to listen on HTTP events (HTTP requests), not on deployment events (startup/shutdown).
CDI/EJB unavailable? Use ServletContextListener
#WebListener
public class Config implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// Do stuff during webapp's startup.
}
public void contextDestroyed(ServletContextEvent event) {
// Do stuff during webapp's shutdown.
}
}
If you're not on Servlet 3.0 yet and can't upgrade (it would be about time because Servlet 3.0 was introduced more than a decade ago), and thus can't use #WebListener annotation, then you need to manually register it in /WEB-INF/web.xml like below:
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
To store and obtain objects in the application scope (so that all servlets can access them), use ServletContext#setAttribute() and #getAttribute().
Here's an example which lets the listener store itself in the application scope:
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("config", this);
// ...
}
and then obtain it in a servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Config config = (Config) getServletContext().getAttribute("config");
// ...
}
It's also available in JSP EL by ${config}. So you could make it a simple bean as well.
CDI available? Use #Observes on ApplicationScoped.class
import jakarta.enterprise.context.ApplicationScoped; // And thus NOT e.g. jakarta.faces.bean.ApplicationScoped
#ApplicationScoped
public class Config {
public void init(#Observes #Initialized(ApplicationScoped.class) ServletContext context) {
// Do stuff during webapp's startup.
}
public void destroy(#Observes #Destroyed(ApplicationScoped.class) ServletContext context) {
// Do stuff during webapp's shutdown.
}
}
This is available in a servlet via #Inject. Make it if necessary also #Named so it's available via #{config} in EL as well.
Noted should be that this is new since CDI 1.1. If you're still on CDI 1.0 and can't upgrade, then pick another approach.
In case you're curious how to install CDI on a non-JEE server such as Tomcat, head to: How to install and use CDI on Tomcat?
EJB available? Consider #Startup#Singleton
#Startup
#Singleton
public class Config {
#PostConstruct
public void init() {
// Do stuff during webapp's startup.
}
#PreDestroy
public void destroy() {
// Do stuff during webapp's shutdown.
}
}
This is available in a servlet via #EJB. The difference with other approaches is that it's by default transactional and in case of #Singleton also read/write locked. So if you would ever need to inject a random EJB (e.g. #Stateless) into a #WebListener or an #ApplicationScoped then you could basically as good merge both into a single #Startup #Singleton.
See also:
How to run a background task in a servlet based web application?
ServletContainerInitializer vs ServletContextListener
How do I force an application-scoped bean to instantiate at application startup?

Unknown JNDI Lookup String

I am new to EJB concept. I have seen the following in different website :
Sample 1:
#Stateless
#EJB(name="audit", beanInterface=AnotherEJBLocal.class)
public class EmployeeBean implements EmployeeServiceLocal, EmployeeServiceRemote {
#PersistenceContext(unitName = "EmployeeService")
private EntityManager manager;
public void doAction(){
try {
Context ctx = new InitialContext();
AnotherEJBLocal audit = (AnotherEJBLocal) ctx.lookup("java:comp/env/audit");
audit.doAnother();
} catch (NamingException e) {
throw new EJBException(e);
}
}
}
Sample 2:
public static void main(String[] a) throws Exception {
EmployeeServiceRemote service = null;
service = (EmployeeServiceRemote) new InitialContext().lookup("EmployeeBean/remote");
service.doAction();
}
Sample 3:
obj = ctx.lookup(ejb/CBDWebAppEAR/CBDWebApp.jar/<EJB name>/<Remote Interface Class Name>);
CBDWebApp is the project name in which the bean resides.
My question is:
What is the need & MEANING of java:comp/env/audit
Why same type of string is not used in case of Sample 2. I guess as
it is a remote EJB not local.
Why is the meaning of the EJB look up string in the Sample 3.
The java:comp/env/audit string is looking up the EJB reference that was declared earlier by the #EJB(name="audit", beanInterface=AnotherEJBLocal.class). Names declared by #EJB (and #Resource and all other EE references) are implicitly declared in the java:comp/env context. With this reference, the deployer can retarget the "audit" reference to any EJB in the application that implements the AnotherEJBLocal interface, or if the deployer doesn't specify anything, the javadoc for the #EJB annotation requires it to target a single EJB within the same application that implements the interface.
This main method is (probably) declared by a standalone Java program. In that case, it (probably) is configured via system properties to connect the JNDI server of an application server, which will return the remote reference to the client. The name that is looked up is vendor-specific, and it was probably configured for the EJB during deployment.
This is very similar to #2, the only difference being the specific string being used. In this case, it is probably relying on an application server's "default" binding name if none was configured for the EJB during deployment using the pattern ejb/<app>/<module>/<bean>/<interface>.

Spring 3.1 ReloadableResourceBundleMessageSource and Apache Tiles 2.2.2

What seemed to be a simple task has turned out to be a few hours of suffering.
I am building a Spring 3.1 MVC application on the JavaEE 6 and Servlet 3.0.1 api without a web.xml file. I have a WebMvcConfiguration class like this fragment:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "be.collectortools.collectorsite")
public class MvcConfig extends WebMvcConfigurationSupport {
#Bean
public ReloadableResourceBundleMessageSource messageSourceBean() {
String[] basenames = {"classpath:messages"};
ReloadableResourceBundleMessageSource resourceBundle = new ReloadableResourceBundleMessageSource();
resourceBundle.setBasenames(basenames);
resourceBundle.setDefaultEncoding("UTF-8");
return resourceBundle;
}
}
I have successfully setup Apache Tiles 2.2.2 together with 2 basic controllers.
Now I would like to add ResourceBundles to the working Spring/Tiles application and I can't get them to work.
After searching I found some this that might go wrong:
Do I use fmt:message key="application.header" or should I use spring:message code="application.header" in my JSP pages? The first ignores not found values the second throws errors.
I use ReloadableResourceBundleMessageSource which should be 'better' or at least newer then ResourceBundleMessageSource is this ok?
ReloadableResourceBundleMessageSource loads files from more locations so I have specified classpath:
I placed the messages.properties file in the src/main/resources folder
Is it still correct that, when not adding a locale to the end of a bundle's name, this is used as a (default) fallback? Either way adding the "en_US" locale doesn't help.
The error:
root cause
javax.servlet.jsp.JspTagException: No message found under code 'application.header' for locale 'en_US'.
org.springframework.web.servlet.tags.MessageTag.doStartTagInternal(MessageTag.java:184)
also the war file is not being run inside Eclipse I deploy it manually to my local tomcat 7.0.23. This also allows me to see the deployed file structure more easily and gives me better control.
I have no clue what is I am doing wrong any help would be appreciated.
The MessageSource bean has to be named messageSource not messageSourceBean - if you change your #Bean to the following it should resolve the messages correctly:
#Bean
public ReloadableResourceBundleMessageSource messageSource() {
String[] basenames = {"classpath:messages"};
ReloadableResourceBundleMessageSource resourceBundle = new ReloadableResourceBundleMessageSource();
resourceBundle.setBasenames(basenames);
resourceBundle.setDefaultEncoding("UTF-8");
return resourceBundle;
}

Resources