How to properly use Weld in JavaFX 2 application? - javafx-2

I'm trying to get Weld to work inside my JavaFX 2 (SE) application (or should I say JavaFX inside Weld?). I have controllers which respond to user interaction. Now I would like to inject my services like a database service for example into these controllers.
Using Weld this should be as easy as :
#Inject
private MyService service;
Now in order to initialise Weld there are three options.
Option 1)
public void main(#Observes ContainerInitialized event) {
launch(); // start JavaFX
}
Option 2)
public static void main(final String[] args) {
new StartMain(args).go();
launch(args);
}
Option 3)
public static void main(final String[] args) {
final WeldContainer weld = new Weld().initialize();
service = weld.instance().select(MyService.class).get();
launch(args);
}
Option 1 and 2 lead to NullPointerExceptions in my controllers because nothing is injected at the annotated injection points. Only option 3 works but this is not really what I need because I do not want the service in my main application class but in my JavaFX controllers instead. With option 3 I would have to pass the initialized service to my controller classes somehow and in this case I do not need Weld. So how do I inject service beans into JavaFX controllers? Unfortunately I found no documentation about my issue.
Maybe someone has gathered experience using Weld and JavaFX and can help me out.
Update
I wrote down some of my efforts in the Weld discussion forum but I got no answer unfortunately. In my opinion Weld does not work with JavaFX. I think I have to insert my services into my controllers using good old setters (see the forum for a solution).
Update 2
I found a blog about Weld and JavaFX 2. I have not tried the solution yet but I think it's useful for other programmers.

Related

I have to integrate ServiceStack together with Kephas. How do I make them both play together with Dependency Injection?

ServiceStack uses a dialect of Funq (no support for metadata), where Kephas uses one of MEF/Autofac (requires metadata support). My question has two parts:
How to make ServiceStack and Kephas use one DI container, if this is possible?
Depending on the answer above: how to make ServiceStack services (like IClientCache) available to Kephas components, knowing that such services may not be annotated with [AppServiceContract]?
You can make ASP.NET and Kephas use one container by choosing to work with Autofac. However, as #mythz pointed out, you will need to provide the Autofac IoC Adapter to the ServiceStack. I don't think you will have any problems with ASP.NET in doing so, as Autofac is the first recommendation of the ASP.NET Core team.
For ASP.NET Core, reference the Kephas.AspNetCore package and inherit from the StartupBase class if you need to be all setup. However, if you need to be in control, have a look at https://github.com/kephas-software/kephas/blob/master/src/Kephas.AspNetCore/StartupBase.cs and write your own Startup class. Another resource that you might find useful is the Kephas.ServiceStack integration package.
Then, additionally to annotating service contracts and service implementations, Kephas allows you to provide service definitions by implementing the IAppServiceInfoProvider interface. These classes are automatically discovered, so this is pretty much everything you have to do.
public class ServiceStackAppServiceInfoProvider : IAppServiceInfoProvider
{
public IEnumerable<(Type contractType, IAppServiceInfo appServiceInfo)> GetAppServiceInfos(IList<Type> candidateTypes, ICompositionRegistrationContext registrationContext)
{
yield return (typeof(IUserAuthRepository),
new AppServiceInfo(
typeof(IUserAuthRepository),
AppServiceLifetime.Singleton));
yield return (typeof(ICacheClient),
new AppServiceInfo(
typeof(ICacheClient),
ctx => new MemoryCacheClient(),
AppServiceLifetime.Singleton));
}
}
Note in the above example that for IUserAuthRepository there is no implementation provided. This indicates Kephas to auto-discover the implementation in the types registered for composition. Alternatively, feel free to use an instance or a factory in the registration, if you need to be deterministic.
I've never heard of Kephas before, but if you're referring to this Kephas Framework on GitHub it says it uses ASP.NET Core in which case it's best if you get them to both use ASP.NET Core's IOC which you can do by either registering your dependencies in ConfigureServices in your App's Startup:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//...
}
}
Or alternatively in ServiceStack's latest v5.6 release for Modular Startup change your ASP.NET Core Startup class to inherit from ModularStartup, e.g:
public class Startup : ModularStartup
{
public Startup(IConfiguration configuration) : base(configuration){}
public new void ConfigureServices(IServiceCollection services)
{
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
}
}
In which case you'll be able to Register ASP.NET Core dependencies in AppHost by registering them in your AppHost's Configure(IServiceCollection) where they can be resolved through both ASP.NET Core's IOC + ServiceStack's IOC, e.g:
public class AppHost : AppHostBase
{
public override void Configure(IServiceCollection services)
{
services.AddSingleton<IRedisClientsManager>(
new RedisManagerPool(Configuration.GetConnectionString("redis")));
}
public override void Configure(Container container)
{
var redisManager = container.Resolve<IRedisClientsManager>();
//...
}
}

Where should I create my ConnectionPool in a JSF application?

I am new to JSF/Facelets and I am creating an application that does the usual CRUD operations over a (No SQL) database. The database has an API that allows the creation of a pool of connections, and then from this object my operations can take and release connections. I suppose this pool has to be created only once for the whole application when it is deployed, be shared (as static?) and closed once the application is destroyed. Is my approach correct? What is the best practice to do this? I have no idea of where I should place my code and how I should call it.
With my old SQL database I used to configure a "testOnBorrow" and a "validationQuery" in the context.xml Resource so I didn't have to create an explicit pool programmatically.
I found two great tutorials (here and here) but I can't figure out from them where to put the code that creates the pool.
Note: I know this might be only a Servlet problem, but I am tagging it as JSF since I don't know if there is a way to do this in JSF (like an application scoped bean). Thanks.
EDIT
Looking at the fact that I cannot find a JAR with a DataSource for the database to be loaded via context.xml, perhaps my question should be more specific: where can I run code once, when a JSF application is deployed and where can I run code when a JSF application is destroyed?
You can implement a weblistner( i.e ServletContextListener). and can use contextInitialized , contextDestroyed method of that to create and destroy your connection pool
Sample :
#WebListener
public class ContextWebListner implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
// initialize connection pool.
}
#Override
public void contextDestroyed(ServletContextEvent event) {
// Destroy connection pool.
}
}

Threads in JSF?

I new in JSF, and I need use Threads for google maps. I am using primefaces for google maps, but I need excute a thread in background to get lat and long from data base and then graphic the markers in the map.
Your question is not specific to JSF, but rather to web applications in general. So, how to perform tasks asynchronously in a Java web applications? Definitely NOT by creating your own threads.
A Java web application runs in an application server (for example jBoss). It is the responsibility of the application server to manage Java threads for you. For instance, it will use a separate thread for each web request that comes in. The application server creates a pool of threads and reuses those threads since it is somewhat expensive to create new ones all the time. That's why you should not create your own, especially if it's done for every web request since it will directly impact scalability.
In order to execute tasks asynchronously, you can use the ejb #Asynchronous annotation (assuming the app is running in a Java EE container like jBoss, but not Tomcat).
import javax.ejb.Singleton;
#Singleton
public class AsyncBean {
#Asynchronous
public void doSomethingAsynchronously() {
// when this EJB is injected somewhere, and this method is called, it will return to the caller immediately and its logic will run in the background
}
}
If the app is not running in a Java EE container, take a look at this answer which nicely lays out some other options for async processing in web apps.
JSF is completely unrelated to your problem. For this case, JSF will act as mere HTML generator. Your specific problem is how to prepare data asynchronously and consume it from your web app.
You can create the thread manually when the application starts on a class that implements ServletContextListener interface, like this:
public class ApplicationListener implements ServletContextListener {
ExecutorService executor;
public ApplicationListener() {
executor = Executors.newSingleThreadExecutor();
}
#Override
public void contextInitialized(ServletContextEvent sce) {
Runnable task = new Runnable() {
#Override
public void run() {
//process the data here...
}
}
executor.submit(task);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
executor.shutdownNow();
}
}
Improve the design above to fulfill your requirements. Take into account that creating threads in an application server should only be done if you know what you're doing.
Another implementation would be to use another application to do the processing (let's call it Data Processor), which by default will run on a separate thread and environment. Then, communicate your web application with this Data Processor through a cache or nosql application like EhCache, Infinispan or Hazelcast.

How to make a serviceloader created class handle container managed objects

I'm currently writing a library where I want the user of my library to implement an interface. From within my library I'm calling this implementation.
I'm using ServiceLoader to instantiate the implementation provided by the integrator and it works just fine. The integrator calls a start() method in my library and in the end he gets something in return. The implementation is used to give me some things along the way that I need in order to get to the final result.
(I'm deliberately not using CDI or any other DI container 'cause I want to create a library that can be used anywhere. In a desktop application, a spring application an application using guice...)
Now I'm facing a problem. I'm creating a showcase in which I'm using my own library. It's a webapplication where I'm using jsf and CDI. When I instantiate the implementation provided in said webapp from within my library, I'm dealing with a non-container managed object. But since this implementation needs to use container managed objects I'm kinda screwed since this can never work.
Example:
Interface in lib:
public interface Example{
public abstract String getInfo();
}
Implementation in war:
public class ExampleImpl implements Example{
#Inject
private ManagedBean bean;
public String getInfo(){
return bean.getSomethingThatReturnsString();
}
}
As you can see this is a huge problem in the way my library is build since the bean will always be null... This means no one using a DI container can use my library. I know I can get the managedbean by doing a FacesContext lookup and get the managedbean but more importantly, my library isn't very well designed if you think about it.
So to conclude my question(s):
Is there any way I can make the serviceloader use a DI container to instantiate the class?
Anyone who knows a better way to fix my problem?
Anyone who knows a better way to get the things I need without making the integrator implement an interface but I can get information from the integrator?
I know this is a quite abstract question but I'm kinda stuck on this one.
Thanks in advance
As the implementation of Example is not performed within the CDI container the injection doesn't happen. What you can do is to lookup the bean manually using the BeanManager. According to the docs, the BeanManager is bound to the jndi name java:comp/BeanManager. Using the following code you can get the BeanManager within your implementation class and lookup the dependencies manually:
InitialContext context = new InitialContext();
BeanManager beanManager = (BeanManager) context.lookup("java:comp/BeanManager");
Set<Bean<?>> beans = beanManager.getBeans(YourBean.class, new AnnotationLiteral<Default>() {});
Bean<YourBean> provider = (Bean<YourBean>) beans.iterator().next();
CreationalContext<YourBean> cc = beanManager.createCreationalContext(provider);
YourBean yourBean = (YourBean) beanManager.getReference(provider, YourBean.class, cc);
where YourBean is the dependency you are looking for.

How can I initialize a Java FacesServlet

I need to run some code when the FacesServlet starts, but as FacesServlet is declared final I can not extend it and overwrite the init() method.
In particular, I want to write some data to the database during development and testing, after hibernate has dropped and created the datamodel.
Is there a way to configure Faces to run some method, e.g. in faces-config.xml?
Or is it best to create a singleton bean that does the initialization?
Use an eagerly initialized application scoped managed bean.
#ManagedBean(eager=true)
#ApplicationScoped
public class App {
#PostConstruct
public void startup() {
// ...
}
#PreDestroy
public void shutdown() {
// ...
}
}
(class and method names actually doesn't matter, it's free to your choice, it's all about the annotations)
This is guaranteed to be constructed after the startup of the FacesServlet, so the FacesContext will be available whenever necessary. This in contrary to the ServletContextListener as suggested by the other answer.
You could implement your own ServletContextListener that gets notified when the web application is started. Since it's a container managed you could inject resources there are do whatever you want to do. The other option is to create a #Singleton ejb with #Startup and do the work in it's #PostCreate method. Usually the ServletContextListener works fine, however if you have more than one web application inside an ear and they all share the same persistence context you may consider using a #Singleton bean.
Hey you may want to use some aspects here. Just set it to run before
void init(ServletConfig servletConfig)
//Acquire the factory instances we will
//this is from here
Maybe this will help you.

Resources