Spring server start-up event - spring

i am facing a problem. I am using tomcat server for my spring maven project and i want to subscribe my application to facebook once when server starts up. I have tried ApplicationListener ContextRefreshedEvent. It gets invoked on application context initialization, but the issue is at that time my server has not completely started and hence my application is not publically accessible which is required in my case as facebook subscription requires verification using application public URL. So i want to do subscription when my server gets started completey and not on application context initialization. Any idea how can i do it? Do i have nay application level event listener that can tell me that server has started completely?
Regards jia

You can annotate a bean method like so :
#PostConstruct
public void yrSubscribeLogic() {}
the app context can only be loaded after the server has fully started.

Related

Registration of dynamic websocket at application initialization time and at runtime has different endpoints exposed

I am trying to register websocket dynamically.For instance, i have registered '/sampleEndpoint' at runtime so ServerWebSocketContainer will register it and start publishing data on that endpoint. But now if i do the same process during application initialization time in PostConstruct than i am unable to connect to '/sampleEndpoint' but have to append '/websocket' at the end so url become '/sampleEndpoint/websocket' when connecting from client side. Why we are getting different endpoints at different situations?
I have attached github url to the code.
https://github.com/pinkeshsagar-harptec/code-sample.git
Well, that's how that SockJS option works: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket-fallback.
If you client is not SockJS, then you have to add that /websocket sub-path.
Not sure though why it doesn't work for dynamically registered endpoints...
In the case of #PostConstruct it is not dynamic: we still do the stuff within configuration phase of the application context, so it is able to add our endpoint into a static HandlerMapping. The dynamic nature is applied a bit later, when all the #PostConstruct have done their logic. You don't need to start that flow registration manually though since the auto-startup phase has not passed yet withing #PostConstruct handling.
Re. IntegrationDynamicWebSocketHandlerMapping: it sounds more like a bug and I need to investigate more. I guess you still use there that SockJS option and it has to be applied for dynamic endpoint as well.
Thank you for your patience! I'll investigate and fix it ASAP.
UPDATE
The fix is here: https://github.com/spring-projects/spring-integration/pull/3581.

How to make spring servlet load-on-startup wait after tomcat jndi (global resources) are loaded

I have a Spring servlet called with load-on-startup = 1 and it requires a database connection, but sometimes, connection is null and the appLoader servlet fails. The connection is null because tomcat didn't had the time to load the global resources properly.
Question : How do I ask Spring to wait for jndi proper loading? I mean, order it in some way.
Dirty solution : Make another servlet with active wait and waiting for a working connection before calling my appLoader...
1) The job of <load-on-startup> is to start a servlet at the time of deployment. It just initiates(starts) the process after that it has no control over that servlet.
The entire control of the started servlet is in the hands of the web container.
The behaviour of the web container can be programmatically controlled using Event Handling mechanism.
2) Events are basically occurrence of something. Changing the state of an object is known as an event.
2.1) You can handle the events of web container using event listeners of servlet and perform some important tasks such as creating tables of the database, creating database connection object etc. at time of deploying the project.
There are many Event classes and Listener interfaces in the javax.servlet and javax.servlet.http package.
You can use ServletContextListener to store the connection object in the context attribute and later fetch that connection object from servlet context.
Here are few examples where database connection object is stored in servlet context. example1 example2 example3
2.2) You can use Event Handling mechanism of spring framework.
In spring you can poll your database connection using ContextStartedEvent that is raised when an ApplicationContext gets started.
Here, are some spring events with example.

Spring Cloud with Liberty

I am currently running a Spring Boot application inside of Websphere Liberty, and use Consul for Service Discovery. To register services with Consul, I created a Liberty feature that hooks in to the Application Lifecycle events and performs the registration /deregistration. This works great, but by doing so I am coupling myself to Liberty. Spring-Cloud-Consul looks like it might solve that issue, but I can't get it to register a service with Liberty (it does connect to Consul) - only with an Embedded Tomcat Server. After looking at the Spring-Cloud-Consul code, the issue is that a EmbeddedServletContainerInitializedEvent isn't being fired, so no port is being set.
My question is, does Spring Cloud Consul only work with embedded servlet containers?
It is a known issue. Feel free to submit a PR. https://github.com/spring-cloud/spring-cloud-consul/issues/173
My solution was to bring spring-cloud-consul's ConsulLifecycle class local and add an ApplicationReadyEvent, like so :
#Autowired(required = false)
private ServerProperties serverProperties;
#EventListener
public void onApplicationReady(ApplicationReadyEvent event) {
this.setConfiguredPort(serverProperties.getPort());
log.info("Application ready on port " + serverProperties.getPort());
this.start();
}
Now my services register and deregister as expected.

Session not removed from SessionRegistry upon logout when using primepush (p:socket) on Weblogic 12c

I have a spring application (spring 4) and using primefaces (version 5.1) for the UI. I've a page where i use p:socket only to get updates from the server:
<p:socket transport="sse" channel="#{backingBean.refreshChannel}" autoConnect="true">
<p:ajax process="#this" update="fplUpdateDialogId" event="message" oncomplete="PF('fplUpdateDialog').show()"/>
</p:socket>
I use tomcat 7 for local development and weblogic 12c for production deployment. Message push to the client works in both application server very well.
The problem here is that the session is not removed from the session registry when the user logs out himself via clicking on the logout button. But this issue occurs only in weblogic. On tomcat it is just fine.
If I remove the p:socket from the page, it works fine. So this must be related to weblogic-primefaces-atmosphere framework triangle (primefaces uses atmosphere framework for pushing messages to the client).
I have debugged and saw that session.invalidate() is being called definitely in the SecurityContextLogoutHandler class (using spring security 3.2.7). Upon session.invalidate(), HttpSessionEventPublisher class, a HttpSessionListener, is informed via calling the sessionDestroyed method. Then HttpSessionEventPublisher publishes HttpSessionDestroyedEvent in the application context. Later the session is removed from the session registry.
On weblogic, even the session.invalidate() is being called, the HttpSessionEventPublisher is not informed about session destroy event. From this point on, i have no clue why. Is this event never fired? If fired, what happened to it? I've searched for hours but could not find a useful hint.

Spring JMS injection causing application not to startup

We have a spring application that publishes and listens to queues on a remote application server. My publisher and listener which are spring based listen within our own application server.
One of the problems we have for our test environments is the other app. server is not up so when our test application goes to start and it tries to inject JmsTemplate with its connectionFactory it blows up because it is not a valid connection and our entire application fails to load. This is causing grief with the other developers in our group that have nothing to do with JMS. All they want to do is run and test their code but the JmsTemplate connectionFactory is down.
Does anyone have any suggestion for enabling spring ignore some bad injections which will allow our application to start properly?
Thanks
I believe this could be achieved by defining separate spring profiles and then passing it as a parameter in your test environments while starting your application. You could mock or ignore any beans then.
Example
import org.springframework.context.annotation.Profile;
#Profile("test")
public class AppConfigTest {
....
....
}
JVM param / System property
-Dspring.profiles.active=test

Resources