PayaraMicro does not call #PreDestroy on EJB or ApplicationScoped - war

I'm migrating a WAR application from PayaraServer to Payara Micro to reduce RAM usage.
I just realise that #PreDestroy on EJBs are not called when stopping the instance with CTRL+C.
Is there a correct way to close the payaramicro instance properly as I'd like to execute some operations.
Thanks for your answers!
Or which services in Payara Server to deactivate to use as much as RAM as PayaraMicro?
I'm using the version 5.183, and I also tried the 5.192.

Which kind of EJB did you use? In my opinion it should work on #Singleton and #Stateless. I am not sure how the other EJBs are supported by Payara Micro.
However, since Payara Micro supports the Java EE Web Profile and you are using a web application anyway, I would suggest to use a #WebListener to get notified of lifecycle events.
It could be implemented as follows:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
#WebListener
public class ContextListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
// do needed setup work here
}
#Override
public void contextDestroyed(ServletContextEvent event) {
// do your cleanup actions here
}
}
Simply add this class to your WAR file then.

Related

ASP.NET 5: How to run function on singleton after creation?

I have an application (a web api) which uses DI. I have a heavy class that will process a lot of text files on startup. It needs about two minutes. I'd like for the application to get going with that as soon as it starts up, rather than when it's first called.
I have read that one should not do any heavy processing in the constructor of DI files, so what's the correct way of doing it? All my class does it provide a string in response to a string. My class unfortunately doesn't support multithreading. How can I make it thread-safe in an easy way? Performance is not a big deal for me. Make sure everything is private and make some kind of token for when it's performing a query?
Edit: I spent some time on it, and here is my Startup class. I made a 'starter' class which receives the MibLibrary class by DI and performs some starting operations on it, that seems to work reasonably well. But I'm really way out of my comfort zone here because I'm not used with DI, so I really wanna learn and take advice of what is best practice, because this will be a production service later on.
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<Appsettings>(Configuration);
services.Configure<MibLibrarySettings>(Configuration.GetSection("Appsettings.MibLibrarySettings"));
services.AddSingleton<MibLibStarter>();
services.AddSingleton<MibLibrary>();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "MibLibApi", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MibLibStarter mibLibStarter)
{
mibLibStarter.Start();
}

dotnet console app, using generic host, HostedService, Windows Task Scheduler stays in running state

Trying to figure out why my console app won't stop running.
Using the following approach in a dotnet core application main method:
await new HostBuilder().
...
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<MyHostedService>();
})
.UseConsoleLifetime()
.Build()
.RunAsync();
Publishing and scheduling that task from the Windows Task Scheduler using the following settings works:
All good so far. All code is properly executed. However, the task stays running, the process never ends. (not even after pressing refresh on the UI of the task scheduler)
Is this expected? If not, how do I get the process to terminate?
If expected, does it still make sense then, to use Generic Host / Hosted Service in a scheduled console app that just starts, runs, and stops?
Answer based on Microsoft.Extensions.Hosting 2.2.0
This behavior is expected, due to your usage of the Generic Host:
It keeps running until shut down or disposed, and you have no shutdown mechanism in place. I assume you expect the Generic Host to shut down after IHostedService.StartAsync(CancellationToken) of your MyHostedService ran to completion. This is not the case, because there might be other IHostedService implementations registered and executed in sequence, and/or a long running BackgroundService which returns control when its ExecuteAsync(CancellationToken) is not completing synchronously to allow other services to run in parallel.
To stop your application gracefully after your MyHostedService completes when running the host via RunAsync, you should constructor-inject the IApplicationLifetime into your MyHostedService and call StopApplication after your Task has completed.
internal class MyHostedService : IHostedService
{
private readonly IApplicationLifetime _appLifetime;
public MyHostedService(IApplicationLifetime appLifetime)
{
_appLifetime = appLifetime;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
await Task.Delay(1000); //your scheduled work
_appLifetime.StopApplication();
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
Also, the application may be stopped via either AppDomain.CurrentDomain.ProcessExit or Console.CancelKeyPress, both events are subscribed to by the ConsoleLifetime, which is pre-registered as the default lifetime implementation.
You can read more about lifetime management in the docs.
Microsoft.Extensions.Hosting 3.0.0 - currently in preview - marked IApplicationLifetime obsolete and recommends using IHostApplicationLifetime instead

Asynchronous logging Service in Spring Boot

I am using 1.5.6.RELEASE to create REST Api that shall store user actions in MS SQLServer database. To make this user action service asynchronous, I have configured #EnableAsync in my main class.
#EnableAsync
public class WebApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(WebApp.class, args);
}
}
#Async
public void saveAction(ActionInfo event) {
actionDataService.save(event);
}
I want to ensure that whatever happens(Server crashes, database goes down etc), user action posted by the client through Rest API service must be saved in database (may be through retry when database comes online or Application server starts again).
Proposed Solutions
Followings are the solutions:
1) Write AsyncUncaughtExceptionHandler to handle exceptions that retries again to save user action. But if Server crashes, the user action objects shall be lost.
2) Use JMS queues to store user action. If Server crashes, the JMS queue should not be lost. It must be able to retry it when server restores. (Just an idea, does not have much knowledge about queues)
Can you please suggest?

Azure web job singleton function is locked

I am using Azure web job to run some logic continuously. The function is a singleton function. However, I am getting "Waiting for lock" message after I tried to run this function after a restart of the web app. Does it mean that another instance of the same function is keeping the lock? How can I resolve this?
The function:
namespace Ns
{
public class Functions
{
[Singleton]
[NoAutomaticTriggerAttribute]
public static async Task ProcessMethod()
{
while(true){
//process logic here
await Task.Delay(TimeSpan.FromSeconds(20));}
}
}
}
The main program:
namespace ns
{
class Program
{
static void Main()
{
var host = new JobHost();
host.RunAndBlock();
}
}
}
The message that I got:
According to the Singleton attribute description the lock is adquired during function execution by a Blob lease.
If another function instance is triggered while this function is
running it will wait for the lock, periodically polling for it.
If you have more than one instance of your App Service Plan, this means that there are more than one Webjob and thus the Dashboard might be showing the locked status of the other Webjobs while one is running.
You can view the blob lease locks that are created on your storage account.
Another option is to try Listener Singletons but I never tried it with Manual triggers.
I disabled the production function in Azure and set the listenerlockPeriod to 15 seconds as described above.
This lessened the locking behavior significantly.

What is the use of #Transactional annotation

I am new to the EJB Projects. And am trying to understand the usage of #Transactional annotation at top of my EJB methods. I have searched for the content and there is no clear explanation on this. Can anyone explain clearly about this.
#Transactional comes from the Spring world, but Oracle finally included it in Java EE 7 specification (docs). Previously, you could only annotate EJBs with #TransactionAttribute annotation, and similar is now possible for CDIs as well, with #Transactional. What's the purpose of these annotations? It is a signal to the application server that certain class or method is transactional, indicating also how it is gonna behave in certain conditions, e.g. what if it's called inside a transaction etc.
An example:
#Transactional(Transactional.TxType.MANDATORY)
public void methodThatRequiresTransaction()
{
..
}
The method above will throw an exception if it is not called within a transaction.
#Transactional(Transactional.TxType.REQUIRES_NEW)
public void methodThatWillStartNewTransaction()
{
..
}
Interceptor will begin a new JTA transaction for the execution of this method, regardless whether it is called inside a running transaction or not. However, if it is called inside a transaction, that transaction will be suspended during the execution of this method.
See also:
TransactionalTxType

Resources