is it possible to get notified inside the bean (mdb in this case) that its deployment procedure has just finished?
I would say that when setMessageDrivenContext is called, that's your bean deployed - you know that the container has a context and has assigned it to your MDB.
The problem with your design is that MDBs are passive components, they're not supposed to do anything until a message gets delivered to them.
I'm pretty sure once the constructor is complete it's considered to be "deployed."
Okay, to address the downvote, from the Jave EE API documentation, you have two lifecycle methods available to you:
void ejbRemove()
A container invokes this method before it ends the life of the message-driven object.
void setMessageDrivenContext(MessageDrivenContext ctx)
Set the associated message-driven context.
Unfortunately, that's it.
Related
I have a project where the client (a Java stateful bean) will make a REST call to another bean (let's call it RequestBean) to perform a function and return a Response. Part of that function requires a call to a vendor's SOAP service. That service is a little slow to initialize in Java, but once initialized, then of course the calls are much faster.
I've been advised that I can move that service initialization to a separate ApplicationScoped bean (let's call it ServiceBean) so that it can initialize once and that's it. My question is about RequestBean. Should that be stateless, and how would it access the service that was initialized in ServiceBean?
I think I've figured this out. I added #Startup #Singleton to the service bean, as well as a method to pass the service reference to the request bean. This works. I'm not sure if this is really the proper way to do this, but for my immediate testing, it's sufficient.
I am very new to Autofac dependency injection and I got these questions related to my project. I have gone through many articles but I am not getting a clear picture on some of the questions I have. Mine is a service application on .Net REST API. I am doing instance registration in App_Start module as shown below.
private static IContainer RegisterServices(ContainerBuilder builder)
{
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<DCLMessengerContext>()
.As<DbContext>()
.ExternallyOwned()
.InstancePerLifetimeScope();
builder.RegisterType<DbFactory>()
.As<IDbFactory>()
.ExternallyOwned()
.InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>()
.As<IUnitOfWork>()
.InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(EntityBaseRepository<>))
.As(typeof(IEntityBaseRepository<>))
.InstancePerLifetimeScope();
builder.RegisterType<PersonServiceClient>()
.As<IPerfService>()
.InstancePerLifetimeScope();
builder.RegisterType<PagingServiceContractClient>()
.As<PagingServiceContract>()
.InstancePerLifetimeScope();
builder.RegisterType<MessageService>()
.As<IMessageService>()
.InstancePerLifetimeScope();
Container = builder.Build();
return Container;
}
My service layer is "MessageService" and there I am performing all the DB and other integration operations and getting the instances through constructor injection. These are the questions I have around this implementation.
I am using InstancePerLifeTimeScope for all my registrations. Is this is the right approach? After the life cycle of each controller request (http request), will these instances will be automatically disposed?
Do we need to manually implement any Dispose operation on any of these instances? ( I don’t have any unmanaged objects in my code)
From the service method, I need to create a fire&forget thread as well using Task.Run(). What is the best approach to supply instances to this fire&forget thread? If I use InstancePerLifeTimeScope, I can see that new thread also getting the same instances that available through the service class so I am just confused when these instances will be disposed?
When you resolve the instance per lifetime scope component, you get a
single instance per nested scope
So if you are using them in controllers. You will have one object for per request and they will be disposed. But if you resolve them in a singleton object they wil live with this object.
Is this is the right approach?
It depends what you need. If you need singleton object, it's not. If you just want to use this service in request scope use instanceperrequest it's better.
Autofac automatically calls dispose for IDisposable objects. If you
need dispose method, implement it. It's not related with autofac.
If you use another thread resolve objects in this thread. Otherwise when request disposed your objects will be disposed and your thread will be fail. Check this.
I am explicitly declaring my registerations as per web request lifecycle but they are still singletons.
this is a problem because my command handlers depend on an IDbConnection which is also registered per web request.
here is my registration code:
container.Register(
Classes
.FromAssemblyContaining<EcruiterCommands>()
.BasedOn(typeof (ICommandHandler<>))
.WithService.AllInterfaces()
.LifestylePerWebRequest());
I found the issue, the culprit is this line:
.BasedOn(typeof (ICommandHandler<>))
it resets the registration.
Say I am using a service A which is imported in another service B. While B is running normally(ofcourse A is Active), what will happen is service A is uninstalled while service B is still running?
Service A -> Service B
What will be the different scenarios in case I am using ServiceReference, ServiceTracker & DS?
When a service is unpublished in OSGi, an event is sent to all bundles currently using that service to tell them that they should stop using it.
If you are using DS, your unbind method will be called. When it is called, you should make best efforts to stop using the service as soon as possible. But ultimately OSGi is a cooperative system, it cannot force you to release the service. However if you don't then you can cause problems, for example the service publisher will not be fully garbage-collected. You end up sabotaging the dynamics of the OSGi platform, possibly creating memory leaks and so on.
If you are using ServiceTracker then the removedService method will be called, and you need to respond in the same way. But didn't I tell you in the other question not to use ServiceTracker?? ;-)
If you are using ServiceReference then you need to explicitly register a ServiceListener in order to receive these events. This is why you really really shouldn't use this low-level API until you have gained a lot more experience (and once you do have that experience, you won't want to use it anyway!).
First of all: one of the advantages of OSGi is that the behaviour of the framework and standard services are clearly specified. Those specifications can be downloaded from the OSGi Alliance web site, or, if you don't like reading PDFs, ordered for print. The question you are asking is perfectly answered in those specifications.
That said, in summary: when a service is unregistered:
The ServiceReference object remains as it is. However, a call to ServiceReference.getService() will return null. Note that when using ServiceReferences you should release any references to the actual service object as retrieved via getService(), this normally requires some kind of tracking of the service.
For ServiceTracker ServiceTracker.remove is called. This normally results in a call to removedService() on the ServiceTracker or the defined ServiceTrackerCustomizer.
For DS, the defined unbind method for the referenced service is called (if specified). Furthermore, if the cardinality for the used service indicates that the service is mandatory, the using service may also be unregistered, even possibly deactivated or a new instance activated depending on the availability of alternative services and the policy defined for the service.
I have a managed bean / service running inside of JBOSS. I then have a quartz job that will occasionally wake up and call a method of the managed bean. This method is sometimes long and drawn out, and since I don't want the quartz job to time out, I have implemented a thread within the managed bean to perform the processing. When the thread is finished I need to update a database table with the results. This is a very serial process and it needs to be based upon some business rules, etc.
My main question is that I can use an EntityManager within the service without a problem however I can not use it from within the thread, I get a NullPointerException. What would be the best way to address this?
Thanks,
Scott
As creating threads in appservers is discouraged, I'd modify the setup a bit.
I'd move the core of processing to a message driven bean, and have the Quartz job just send a message to the queue on which the MDB is listening. The MDB in turn can call your EJB, and like this everything remains within what's allowed by the standard.
As per the documentation and specification the Entity Manager is not thread safe and can not be used across different child threads as I had originally had in mind. I ended up going back to the original design similar to the one provided by fvu, however I found some annotations that would allow me to modify the been timeout period and allow the long running process to work properly. Here's the annotation that I used:
#PoolClass(value=org.jboss.ejb3.StrictMaxPool.class, timeout=360000000L)