Guice: Scope related questions - java

I'd like to use a dependency injection framework.
During my evaluation I came to the conclusion that Google Guice seems to fit best for my demands.
However, some questions came into my mind:
Imagine a web application in which a user can have independent windows within a http session. The Session scope is too general while the Request scope is too narrow for me. Is there a scope which will help me out? (something I would call "window" or "controller instance" scope)
Are there any pitfalls writing a custom scope?
Our web application and several stand alone console applications are using the same classes. I am facing the problem that the scope of a class depends on the application type which is only known at runtime.
E.g. in a standalone application the scope would be "No-Scope" or "per-Thread Scope", while in a web application it would be bound to a Session/"window".
How to solve this problem?

You'll have to create a custom scope
Not that I know. We've been using a custom scope and it works very well.
Have a different implementations of the custom scope being used in the web application and other for the standalone application

To answer 3. use different modules for your versions, and set the scopes there.
bind(Grill.class).to(Applebees.class).in(Scopes.SINGLETON);

You can use scope with application context handlers which help in deciding how your scoping logic works. Then using the same custom scope you can control how the objects get created at runtime.

Related

Dynamic class loading in OSGi

I have a whole bunch of framework modules that work fine on OSGi, all the services and components are finding one another and running just fine.
There is however one framework that does some dynamic stuff regarding classes. Basically at some point you give it a class name and it performs Class.forName() and then reflection magic happens.
This works great when running in a standard jvm and using SPI to wire together the frameworks but it fails in OSGi because of course that random class "test.MyTest" that you are trying to approach via the framework is not visible to said framework.
It will throw a "java.lang.ClassNotFoundException: test.MyTest not found by framework"
So my question: how can I solve this lack of visibility for the framework that needs to see all? Import-Package: *?
UPDATE
Assuming OSGi hasn't changed much since 2010 on this front, the article http://njbartlett.name/2010/08/30/osgi-readiness-loading-classes.html is very interesting. I have currently added support for both actively registering classes and a domain factory to be injected via OSGi.
Apart from that the default resolving uses context classloader anyway so if all else fails that will be used to try and load the class.
UPDATE
I have added support for the suggested DynamicImport-Package as well which is easier for small projects.
You can use DynamicImport-Package:*. This will allow the bundle to see all classes. The problem is that you have no real control over what exactly is exposed. So this is normally a last resort and not the recommended way.
You should first try to use Thread.currentThread().setContextClassLoader() and set it to the classloader of the class you provide to the framework. Sometimes the frameworks also consult this classloader.
The even better way is to find a method in the framework that allows to provide the user classloader.
If you have control over the code then avoid Class.forName(). Instead let the user either give you a class object instead of a class name or let the user give you the combination of a class name and the classloader to use. Both ways work perfectly in and outside OSGi.

Tomcat keep webapp api running

I'm trying to create a web application for tomcat 7, but my problem is that I want to keep the whole backbone of the application running, so that my servlets can call the functions. Ex. I have my com.example.Main class which house all the instances to things like User managers and such. But instead of getting the main instance redefined on each servlet call, It would get defined once for all the servlets to use.
Best Regards,
- Roe
As far as I understand, you want a singleton. Check this answer for implementation.
But note that singletons are "evil". A more webapp approach is to not have it as singleton, but initialize it once in a ContextLoaderListener and then put it as a ServletContext attribute. Then each servlet can obtain it by getting it from the servlet context.
I agree with Bozho - you seem to be talking about a Singleton and I share his reservations about using them.
If you do implement it as a singleton, or use Bozho's suggested solution, it is important for you to understand that there will be only one instance of the class, potentially being used by many servlets at the same time. As a result, it is your responsibility to make sure that the class is thread safe, or your application will produce unreliable results.

Apache Tomcat: "Context variable"

I'm new to Tomcat and hence have a few question. I want to have certain objects available for my Context from any code. I was able to achieve this for a DataSource because that is the example used in the Tomcat guide.
I would like to add 2 additional objects:
Object A that uses this DataSource in the Constructor
Object B that uses Object A in it's constructor
How can I do this?
What's probably the easiest thing to do is use a ContextListener that inserts Objects A and B into the Context. See http://download.oracle.com/javaee/1.4/tutorial/doc/Servlets4.html for a usage example: in the contextInitialized method you can grab the datasource out of the context, create objects A and B and then store them back into the context.
According to the Tomcat 5.5 spec. found on http://tomcat.apache.org/tomcat-5.5-doc/config/globalresources.html I see that Context is not capable of doing such tricks and is not for such usages.
You'd like to have some objects available from "any code". If this any is confined to a single web application, than you can consider #Fermi's answer or maybe you should launch a Spring ApplicationContext. That might sound a bit too difficult if you're not familiar with Spring Framework yet, however if you keep developing your application I think there will be a certain point where things start to become easier if a Spring context already exists from the beginning. (Tell me in a comment if you need help with setting up Spring provided you choose that way.)

How to modularize a JSF/Facelets/Spring application with OSGi?

I'm working with very large JSF/Facelets applications which use Spring for DI/bean management.
My applications have modular structure and I'm currently looking for approaches to standardize the modularization.
My goal is to compose a web application from a number of modules (possibly depending on each other). Each module may contain the following:
Classes;
Static resources (images, CSS, scripts);
Facelet templates;
Managed beans - Spring application contexts, with request, session and application-scoped beans (alternative is JSF managed beans);
Servlet API stuff - servlets, filters, listeners (this is optional).
What I'd like to avoid (almost at all costs) is the need to copy or extract module resources (like Facelets templates) to the WAR or to extend the web.xml for module's servlets, filters, etc. It must be enough to add the module (JAR, bundle, artifact, ...) to the web application (WEB-INF/lib, bundles, plugins, ...) to extend the web application with this module.
Currently I solve this task with a custom modularization solution which is heavily based on using classpath resources:
Special resources servlet serves static resources from classpath resources (JARs).
Special Facelets resource resolver allows loading Facelet templates from classpath resources.
Spring loads application contexts via the pattern classpath*:com/acme/foo/module/applicationContext.xml - this loads application contexts defined in module JARs.
Finally, a pair of delegating servlets and filters delegate request processing to the servlets and filters configured in Spring application contexts from modules.
Last days I read a lot about OSGi and I was considering, how (and if) I could use OSGi as a standardized modularization approach. I was thinking about how individual tasks could be solved with OSGi:
Static resources - OSGi bundles which want to export static resources register a ResourceLoader instances with the bundle context. A central ResourceServlet uses these resource loaders to load resources from bundles.
Facelet templates - similar to above, a central ResourceResolver uses services registered by bundles.
Managed beans - I have no idea how to use an expression like #{myBean.property} if myBean is defined in one of the bundles.
Servlet API stuff - use something like WebExtender/Pax Web to register servlets, filters and so on.
My questions are:
Am I inventing a bicycle here? Are there standard solutions for that? I've found a mentioning of Spring Slices but could not find much documentation about it.
Do you think OSGi is the right technology for the described task?
Is my sketch of OSGI application more or less correct?
How should managed beans (especially request/session scope) be handled?
I'd be generally grateful for your comments.
What you're aiming to do sounds doable, with a few caveats:
The View Layer: First, your view layer sounds a little overstuffed. There are other ways to modularize JSF components by using custom components that will avoid the headaches involved with trying to create something as dramatic as late-binding managed beans.
The Modules Themselves: Second, your modules don't seem particularly modular. Your first bullet-list makes it sound as if you're trying to create interoperable web apps, rather than modules per se. My idea of a module is that each component has a well-defined, and more or less discrete, purpose. Like how ex underlies vi. If you're going down the OSGi route, then we should define modular like this: Modular, for the sake of this discussion, means that components are hot-swappable -- that is, they can be added and removed without breaking the app.
Dependencies: I'm a little concerned by your description of the modules as "possibly depending on each other." You probably (I hope) already know this, but your dependencies ought to form a directed acyclic graph. Once you introduce a circular dependency, you're asking for a world of hurt in terms of the app's eventual maintainability. One of the biggest weaknesses of OSGi is that it doesn't prevent circular dependencies, so it's up to you to enforce this. Otherwise your dependencies will grow like kudzu and gradually choke the rest of your system's ecosystem.
Servlets: Fuhgeddaboudit. You can't late-bind servlets into a web app, not until the Servlet 3.0 spec is in production (as Pascal pointed out). To launch a separate utility servlet, you'll need to put it into its own app.
OK, so much for the caveats. Let's think about how this might work:
You've defined your own JSF module to do... what, exactly? Let's give it a defined, fairly trivial purpose: a login screen. So you create your login screen, late-bind it using OSGi into your app and... then what? How does the app know the login functionality is there, if you haven't defined it in your .jspx page? How does the app know to navigate to something it can't know is there?
There are ways to get around this using conditional includes and the like (e.g., <c:if #{loginBean.notEmpty}>), but, like you said, things get a little hairy when your managed loginBean exists in another module that may not have even been introduced to the app yet. In fact, you'll get a servlet exception unless that loginBean exists. So what do you do?
You define an API in one of your modules. All the managed beans that you intend to share between modules must be specified as interfaces in this API layer. And all your modules must have default implementations of any of these interfaces that they intend to use. And this API must be shared between all interoperable modules. Then you can use OSGi and Spring to wire together the specified beans with their implementation.
I need to take a moment to point out that this is not how I would approach this problem. Not at all. Given something like as simple as a login page, or even as complicated as a stock chart, I'd personally prefer to create a custom JSF component. But if the requirement is "I want my managed beans to be modular (i.e., hot-swappable, etc)," this is the only way I know to make it work. And I'm not even entirely sure it will work. This email exchange suggests that it's a problem that JSF developers have only just started to work on.
I normally consider managed beans to be part of the view layer, and as such I use them only for view logic, and delegate everything else to the service layer. Making managed beans late-binding is, to my mind, promoting them out of the view layer and into the business logic. There's a reason why all those tutorials are so focused on services: because most of the time you want to consider what it would take for your app to run "headless," and how easy it would be to "skin" your view if, for instance, you wanted it to run, with all its functionality, on an Android phone.
But it sounds like a lot of what you're working with is itself view logic -- for instance, the need to swap in a different view template. OSGi/Spring should be able to help, but you'll need something in your app to choose between available implementations: pretty much what OSGi's Service Registry was built to do.
That leaves static resources. You can modularize these, but remember, you'll need to define an interface to retrieve these resources, and you'll need to provide a default implementation so your app doesn't choke if they're absent. If i18n is a consideration, this could be a good way to go. If you wanted to be really adventurous, then you could push your static resources into JNDI. That would make them completely hot-swappable, and save you the pain of trying to resolve which implementation to use programmatically, but there are some downsides: any failed lookup will cause your app to throw a NamingException. And it's overkill. JNDI is normally used in web apps for app configuration.
As for your remaining questions:
Am I inventing a bicycle here? Are there standard solutions for that?
You are, a little. I've seen apps that do this kind of thing, but you seem to have stumbled into a fairly unique set of requirements.
Do you think OSGi is the right technology for the described task?
If you need the modules to be hot-swappable, then your choices are OSGi and the lighter-weight ServiceLocator interface.
Is my sketch of OSGI application more or less correct?
I can't really tell without knowing more about where your component boundaries are. At the moment, it sounds like you may be pushing OSGi to do more than it is capable of doing.
But don't take my word for it. I found other reading material in these places.
And since you ask about Spring Slices, this should be enough to get you started. You'll need a Git client, and it looks like you'll be training yourself on the app by looking through the source code. And it's very early prototype code.
I am facing the same problems in my current project. In my opinion, OSGi is the best and cleanest solution in terms of standards and future support, but currently you may hit some problems if you try using it in a web application:
there is no well integrated solution between a Web Container and the OSGi platform yet.
OSGi may be too much for a custom build web application that is just searching for a simple modularized architecture. I would consider OSGi if my project needs to support third party extensions that are not 100% under our control, if the project needs hot redeployments, strict access rules between plugins, etc.
A custom solution based on class loaders and resource filters seems very appropriate for me.
As an example you can study the Hudson source code or Java Plug-in Framework (JPF) Project(http://jpf.sourceforge.net/).
As about extending the web.xml, we may be lucky with the Servlet 3.0 specification(http://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html#pluggability-and-extensibility).
The "web module deployment descriptor fragment" (aka web-fragment.xml) introduced by the Servlet 3.0 specification would be nice here. The specification defines it as:
A web fragment is a logical
partitioning of the web app in such a
way that the frameworks being used
within the web app can define all the
artifacts without asking devlopers to
edit or add information in the
web.xml.
Java EE 6 is maybe not an option for you right now though. Still, it would to be the standardized solution.
Enterprise OSGi is a fairly new domain so dont think you will get a solution that directly satisfies your need. That said one of the things I found missing from Equinox (osgi engine behind eclipse and hence one with largest user base!) is a consistent configuration / DI service. In my project recently we had some similar needs and ended building a simple configuration osgi service.
One of the problems which will be inherent to modular applications would be around DI, as the module visibility could prevent class access in some cases. We got around this using a registered-buddy policy, which is not too ideal but works.
Other than configuration, you can take a look at the recently released Equinox book for guidance on using OSGi as base for creating modular applications. The examples may be specific to Equinox, but the principles would work with any OSGi framework. Link - http://equinoxosgi.org/
You should look into Spring DM Server (it's being transitioned to Eclipse Virgo but that's not been released yet). There's a lot of good things in the recent OSGi enterprise spec which has also just been released.
Some of the Spring DM tutorials will help, I'd imagine. But yes, it's possible to have both resources and classes loaded from outside the web bundle using standard modularity. In that, it's a good fit.
As for the session context - it gets handled as you would expect in a session. However, you might run into problems with sharing that session between web bundles to the extent that in not sure if it's even possible.
You could also look to have a single web bundle and then use e.g. the Eclipse extension registry to extend the capabilities of you web app.

Proper ApplicationContext usage?

I've recently started learning the Spring Framework, and I'm a bit unclear on how the ApplicationContext is supposed to be used - in both standalone and web applications. I understand that the ApplicationContext, once instantiated with the spring configuration xml, is the "spring container" and is a singleton.
But:
In the starting point - main method - of an app do I use ApplicationContext.getBean("className") and then rely on DI for all other registered beans or is there a way to use only DI?
Is there any other place besides the main method where I could/should use ApplicationContext.getBean("className")?
If and when should ApplicationContext.getBean("className") be used in a web app?
If in your opinion there is information I MUST know regarding DI related to web applications, even though I may not of specifically inquired about it, please share.
You need at least one call into the context from outside it, there's no avoiding that. With webapps, that part is hidden from you, and it it feels like everything is using DI, even though Spring's servlet glue code is doing some unpleasantness behind the scenes.
Could, yes; should, no. There are very few good reasons for calling getBean yourself.
The most obvious scenario is when you have a servlet filter that needs access to the context. FIlters aren't managed by Spring, and so cannot have stuff wired into them by Spring.
That's a bit too vague. Read the reference docs :)
I generally recommend only one usage of ApplicationContext.getBean() per application, and rely on the Spring configs to do the rest.
The exception applies in unit tests, where I want to load up a particular subset of beans (so I would explicitly load a bean that normally would be loaded from the top of my bean hierarchy).

Categories