#PostConstruct called twice on simple #Singleton #Startup bean - java

my problem is that the #PostConstruct is called twice even though it shouldn't. I searched a lot and found similiar problems with jersey https://java.net/jira/browse/JERSEY-1883?filter=-3. However I tried to make a small example which apparently still causes the problem even without any clatter.
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
#Singleton
#Startup
public class TestSingleton {
#PostConstruct
public void init() {
System.out.println("How many times am I being called?");
}
}
Configuration
Application server: Glassfish 3.1.2
Java Version: JDK 1.7_17
Packaging: A war file within an ear
Any ideas?

I figured it out by using #PreDestroy or Publish of the application server.
The problem is "normal". With using Eclipse as an IDE after the server start the application will be published again. Therefore you'll only see one log message of #PreDestroy but two of #PostConstruct.
The same goes for changing something and publishing afterwards. Here you should only see the message from #PostConstruct once.
Then you'll know everything is alright.

#PostConstruct —This is invoked immediately after a bean instance is created.
You can see this :
#Startup #Singleton instantiated twice in WebLogic (EJB 3.1)

Related

Jakarta EE 10 #Startup on K8S

Stack
Java
Jakarta EE 10
JBoss/Widlfly 27
Kubernetes K8S
JAX-RS (RestEasy)
I want to initialize some caches on startup of my app. During that time i want my readiness probe to respond not ready.
With the management inteface turned on, this works BUT not with my classes, instead the standard one responds.
Wildfly runs in standalone mode.
What i try to accomplish is to run my OWN code for readiness/live BUT that these endpoints are available during startup. I created my own outside of microprofile.healt but they are not available during startup.
Does anybody have some ideas?
Below is my code
import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.Liveness;
import org.eclipse.microprofile.health.Readiness;
/**
* Created by Gerry Askefalk on: 2023-01-13
*/
#ApplicationScoped
#Liveness
#Readiness
public class Mycheck implements HealthCheck {
#Override
public HealthCheckResponse call() {
return HealthCheckResponse.named("mycheck").up().build();
}
}
Ok
the solution (and my bad) was to not add microprofile extensions to WF.
When i did, it works!
This article explained it to me.
microprofile on wf

Inject of remote EJB interface into external module

I have an EAR application with three modules:
beans are in "app-ejb" module
remote interfaces are in "app-remote"
web services are in "app-war"
app-ejb and app-war use app-remote as library.
all are packaged in "app.ear".
This is working fine, but now I have to use the same beans outside the EAR application, and injection is not working.
I have in app-ejb:
#Stateless
#LocalBean
public class Services implements ServicesRemote {
[...]
}
and his remote interface in app-remote:
#Remote
public interface ServicesRemote {
[...]
}
In my app-war I can inject the remote bean without problem:
#Stateless
#LocalBean
public class UseServices {
#EJB
private ServicesRemote services;
[...]
}
Anyway in my external ejb application, deployed as stand-alone and using the same ejb-remote as library, if I try to inject the same EJB like this:
#Stateless
#LocalBean
public class UseServicesFromAnotherApp {
#EJB
private ServicesRemote services;
[...]
}
Glassfish (4.1) give me an error "Class [ Lcom/[...]/ServicesRemote; ] not found".
Is this expected? How can I inject the remote bean correctly?
Injection doesn't work with remote interfaces. Beans that are "injectable", live inside container's JVM and are available for injection to other beans inside the same application. The same holds true for accessing beans in another application in the same container, although applications may live in the same JVM. Since remote methods are originated from another JVM or another application, injection is not possible. You must use JNDI lookup instead to get a reference to a remote bean.
As a matter or personal taste, I would stay away from EJB Remote interfaces, and instead I would use another "remoting" technique such as REST.
The problem was probably generated by a number of hot deploys, made glassfish unstable.
When I restarted glassfish my code start to work properly (it's actually still working).
Sorry for posting here without trying to restart glassfish first.

CDI can't set #Singleton into #Provider in #Requestscoped REST service after redeploy on WildFly

I have AuthenticationFilter and it injects UserController which is annotated with #Singleton. When I deploy my application for the first time - everything is all right, but when I redeploy application and then I try to get something from whichever REST service - often I receive:
Can not set app.auth.UserController field
app.web.rest.auth.AuthenticationFilter.userController to
app.auth.UserController$Proxy$_$$_Weld$EnterpriseProxy$
The problem still occurs even if I kill server and restart it. But after couple of restarts issue finally disappears.
Someone knows what could cause that error?
I had experienced this problem too. With each deployment I would get random fails of injecting (EJB) #Singleton and even (CDI) ApplicationScoped.
The problem in my case was that I did not have beans.xml. Somehow without the beans.xml the project did not initialize properly.
When I added (a completely empty) beans.xml it was resolved. Hope it helps.

Spring not registering #ManagedBean

I am looking at building a web application using wicket, running on a jetty server, and want to use spring as IoC framework. To test this setup I made a small web app. I am having spring doing a component scan to look up my beans. The test app has only one such bean, annotated with #ManagedBean. An instance of this bean is injected into a wicket WebPage.
The problem is that this works on my development machine, using embedded jetty, but not on my production machine, running jetty as a service.
I have tracked the problem down up to ClassPathScanningCandidateComponentProvider.registerDefaultFilters().
On my development machine filters are registered for:
org.springframework.stereotype.Component
javax.inject.Named
javax.annotation.ManagedBean
My production machine only provides the first two, missing my #ManagedBean annotation.
First I thought maybe I was using a different version of ClassPathScanningCandidateComponentProvider, but, using -verbose:class, showed that it is only loaded once, from spring-context-4.0.2.RELEASE.jar.
As a workaround I can annotate my beans with #Component instead of #ManagedBean, but would still like to know why the ManagedBean filter is not registered.
Even though verbose class loading seems to suggest otherwise I still suspect I am using different versions on my two machines.
If anyone can point me in the direction of a solution to this problem it would be greatly apreciated.
Thanks in advance.
My web page is as follows:
public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;
#SpringBean
private SpringTestClass test;
public HomePage(final PageParameters parameters) {
..
My bean is annotated as follows:
#ManagedBean
public class SpringTestClass {
Am am using:
Jetty 9
Spring 4.0.2
Wicket 6.0

JBoss AS 7 - After Startup initialization

Is there any way to catch an event/implements a Class, or something like that, to detect that JBoss (AS7) is up and running and all applications has been deployed ?
I made a StartupServlet (which extends HttpServlet) because i need to call a local web service to initialize the system. But because my application is not fully deployed my call for the web service (in the StartupServlet) ends in a "404 Not Found error".
I tried to use a <listener>...</listener> on the web.xml but it's not working.
You can try using a Startup EJB, like explained here:
#Singleton
#Startup
public class StartupBean {
#PostConstruct
private void startup() { ... }
#PreDestroy
private void shutdown() { ... }
}
However the bean will not detect whether your applications are deployed, only that the current application - the one containing the bean - is deployed and started. Since the #PostConstruct method is called very early, you cannot rely on any other beans or services being available.
EDIT: Jboss also has a native management API. AFAIK it can also be used to query deployments. Unfortunately it's documentation is not really impressive, but perhaps you can figure it out.
According to my understanding, you do not need to detect when all application was deployed, you need to understand only if your application was deployed. To do it you should define ServletContextListener:
http://docs.oracle.com/javaee/5/api/javax/servlet/ServletContextListener.html#contextInitialized%28javax.servlet.ServletContextEvent%29
Than you can catch when it deployed:
public void contextInitialized(ServletContextEvent sce)
{
servletContext = sce.getServletContext();
}

Categories