After a cursory inspection, it seems like SLF4J and Guice (well, any DI framework, really) are sort of conflicting philosophies. SLF4J takes the approach "hey, we won't know until runtime what classes we're going to bind to, and that's OK." Guice, on the other hand, seems to say "hey, we need to know at compile-time exactly what classes we're binding to.".
So I ask: is it possible to use Guice/Spring/whatever DI framework to configure/inject SLF4J bindings?
The kicker is that the Java ClassLoader is what is really "injecting" SLF4J at runtime with the proper Logger/LoggerFactory/etc. objects, so I can't figure out how to inject those ClassLoaders so that they returns the org.slf4j.impl.Logger that I want at runtime:
I ask because I like the benefit of SLF4J and logging against an API, but also like the benefits of DI. Is there a way to make this work? Thanks in advance!
I believe it is not possible (unless you make something extremely cumbersome, like a container that create child classloader for your app... something like that)
The basic idea of SLF4j to have replaceable implementation is by having the binder lib providing the org.slf4j.impl.StaticLoggerBinder and SLF4J API will lookup this class thru classloader. Hence, if there is more than 1 binder in classpath, there is no way to distinguish the org.slf4j.impl.StaticLoggerBinders they are providing. DI framework is not going to help on this, given that Logging framework initialize even before DI happens.
Unless SLF4J is changing its design in the future, there is not much way we can do. And, I doubt it is possible even SLF4J changes its design. As we have no way to tell the DI container that the Logging initialization is something everybody depends on. I believe there are more reasons make it almost impossible to achieve.
However, what I am in doubt is, does this really have to do with DI? Honestly I don't see the problem of controlling which logging binding to use by putting corresponding JAR in classpath. If you want to control it on runtime, kind of programmatically, I think writing a little container to launch your app is the way to go. However, it is still nothing to do with DI.
One rather simple approach to this problem is to inject a ILoggerFactory instance into LoggerFactory via the setILoggerFactory() method. (As of October 2012, the setILoggerFactory() method does not exist.)
The static binding mechanism currently implemented by SLF4J does not do much other than setting the ILoggerFactory. Would such an approach work for you?
For anyone finding this now: Sangria implements a "context-sensitive binder" that works very well for this; see sangria-slf4j and sangria-contextual specifically.
From the author's blog post, you can set up an SLF4J named logger factory as easily as:
public class YourModule extends AbstractModule {
#Override
protected void configure() {
install(new SangriaSlf4jModule());
}
}
...and there are examples of how to use the new providers for your own types as well.
Related
I think my understanding of spring beans is a bit off.
I was working on my project and I was thinking about this situation.
Say I have class Foo
class Foo(){
public void doSomething(Object a , Object b){ // input parameters does not matter actually.
//do something
}
}
If I am using this class in another class like :
class Scheduler{
....
#Autowired
private Foo foo;
someMethod(){
foo.doSomeThind(a,b);
}
....
}
In the above case Instead of Autowiring the Foo, I can make doSomeThing static and directly use Foo.doSomeThing(a,b)
I was just wondering if there any advantage of creating a bean or if there any disadvantage of using static methods like this?
If they are same, When should I go for spring bean and when should do I simply use a static method?
Static methods are ok for small utility functions. The limitation of static code is that you can't change it's behavior without changing code itself.
Spring, on the other hand, gives you flexibility.
IoC. Your classes don't know about the exact implementation of their dependencies, they just rely on the API defined by interface. All connections are specified in configuration, that can be different for production/test/other.
Power of metaprogramming. You can change the behavior of your methods by merely marking them (via annotations of in xml). Thus, you can wrap method in transactions, make it asynchronous or scheduled, add custom AOP interceptors, etc.
Spring can instrument your POJO method to make it an endpoint to remote web service/RPC.
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/
Methods in Spring beans can benefit from dependency injection whereas static methods cannot. So, an ideal candidate for static method is the one that does things more or less independently and is not envisioned to ever need any other dependency (say a DAO or Service)
People use Spring not because of some narrow specific futures that cannot be replaced by static classes or DI or whatever. People use Spring because of a more abstracted features and ideas it provide out of the box.
Here is a nice quote from Someone`s blog:
Following are some of the major benefits offered by the Spring Framework:
Spring Enables POJO Programming. Spring enables programmers to develop enterprise-class applications using POJOs. With Spring, you are able to choose your own services and persistence framework. You program in POJOs and add enterprise services to them with configuration files. You build your program out of POJOs and configure it, and the rest is hidden from you.
Spring Provides Better Leverage. With Spring, more work can be done with each line of code. You code in a more fast way, and maintain less. There’s no transaction processing. Spring allows you to build configuration code to handle that. You don’t have to close the session to manage resources. You don’t have to do configuration on your own. Besides you are free to manage the exceptions at the most appropriate place not facing the necessity of managing them at this level as the exceptions are unchecked.
Dependency Injection Helps Testability. Spring greatly improves your testability through a design pattern called Dependency Injection (DI). DI lets you code a production dependency and a test dependency. Testing of a Spring based application is easy because all the related environment and dependent code is moved into the framework.
Inversion of Control Simplifies JDBC. JDBC applications are quite verbose and time-taking. What may help is a good abstraction layer. With Spring you can customize a default JDBC method with a query and an anonymous inner class to lessen much of the hard work.
Spring’s coherence. Spring is a combination of ideas into a coherent whole, along with an overall architectural vision to facilitate effective use, so it is much better to use Spring than create your own equivalent solution.
Basis on existing technologies. The spring framework is based on existing technologies like logging framework, ORM framework, Java EE, JDK timers, Quartz and other view related technologies.
During unit testing you have more flexibility using bean because you can easily mock your bean methods. However, that is not the same with static methods where you may have to resort to PowerMock (which I recommend you stay away from if you can).
It actually depends on the role of the component you are referring to: Is this feature:
An internal tooling: you can use static (you wouldn't wrap Math.abs or String.trim in a bean)
Or a module of the project: design it to be a bean/module-class (a DAO class is best modular to be able to change/mock it easily)
Globally, you should decide w.r.t your project design what are beans and what are not. I think many dev put too much stuff inside bean by default and forget that every bean is an public api that will be more difficult to maintain when refactoring (i.e. restrained visibility is a good thing).
In general, there are already several answers describing the advantages of using spring beans, so I won't develop on that. And also note that you don't need spring to use bean/module design. Then here are the main reasons not to use it:
type-safety: Spring bean are connected "only" at runtime. Not using it, you (can) get much more guaranties at compile time
It can be easier to track your code as there is no indirection due to IoC
You don't need the additional spring dependency/ies which get quite heavy
Obviously, the (3) is correct only if you don't use spring at all in your project/lib.
Also, The (1) and (2) really depend on how you code. And the most important is to have and maintain a clean, readable code. Spring provides a framework that forces you to follow some standard that many people like. I personally don't because of (1) and (2), but I have seen that in heterogeneous dev teams it is better to use it than nothing. So, if not using spring, you have to follow some strong coding guidelines.
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.
I'm writing a framework that uses Guice to bootstrap a server, and so I've extended Guice's AbstractModule to create a Module that provides some convenience methods for users to configure their code. However, I want to to check that the configuration is sane before launching the code. So it has to go somewhere in here:
// here, before the injector is created?
Injector injector = Guice.createInjector(someModule);
// here, after configure() is called?
Object something = injector.getInstance(SomeServer.class);
// start the server
It seems that there's not much I can check before the injector is created because the modules are not configure()ed yet. There is some mention of using the Guice SPI to validate module configuration, but the documentation is not too clear. Can someone, who uses Guice, give a short description on the best practices for validating modules before injectors are used?
I haven't experienced much of this first-hand, but it seems to me that you have three choices:
Refactor to MyConvenienceMethodModule.myConfigure() and MyConvenienceMethodModule.validate() if your convenience methods are expressive enough to provide useful information without ever running configure(). In theory you could call Module.configure(Binder) with a mock, but with Guice's EDSL that's far too complex; use ElementVisitor (below) instead.
Call Elements.getElements() on a particular Module to check on the binding status. Because the elements might be of a variety of types, you'd probably want to create an ElementVisitor instead (probably by creating a subclass of DefaultElementVisitor to insulate you from future Elements yet to be created). This way you get a good view of all bindings, even bindings in Guice's EDSL, while still in the context of the Module. I think this is your best bet.
Create your Injector as usual and call getAllBindings() to investigate it. This is probably your best option if your configuration's sanity depends on how multiple modules interact, rather than how individual modules are structured. If you only check at this point, you won't really be able to tell one Module from another.
I'm working on a project, where it is needed to load some classes at runtime. The classes to load are parts of CDI-Containers and have to be able to inject some stuff. The "loading class" itself is a part of a CDI-Container as well.
Now comes my problem. It is possible to load and instantiate any class via reflection, but in this case it would not be possible for the classes to be loaded to get anything injected. So it is needed to get an instance of these classes as it would be internally done by the server like when we would use the annotation #javax.inject.Inject.
Is there any way to load the classes of another CDI-container in a way that they can still work with Injections (otherwise it would not make any sense^^)? Maybe there is any kind of Class which is responsible for for handling all of these classes so that I can simply tell it the name of the class to load (as I would do it with reflections)... ?
Thanks
You can use the BeanManager API to query and laod contextual references based on bean types.
Review your design carefully, as it sounds like you're entering into "procedural style" programming rather than OO. This is likely the first of many problems with your design you're likely to encounter.
I have an idea that might work though; can you make these classes implement a certain interface? If they do, you can use normal #Inject annotations in your code with the interface, then stuff the class implementation into a /lib directory on a server. This, combined with CDI alternatives may be able to get you what you want.
A better approach may be to use reflection and some kind of factory...
We basically need to be able to adjust behaviour at start-up time, by providing desired classes to be produced by various factories inside our application (to avoid the hard binding of the "new" operator).
I am aware that this is provided by several large frameworks, but I was looking for something easily used by a stand-alone Java application without being gigantic.
Any suggestions?
Edit: It is my experience that frameworks tend to grow big as part of maturing (and complex too). I need this to be retrofittable to a legacy application as part of major refactoring (technical debt), so simplicity is essential of the used libraries. I do not mind having to do a bit of coding in our application, but it must be very visible what is going on. AOP has a tendency for moving stuff out of the way, and that may make the application harder to maintain.
Edit: We have now reached the point where we actually need to make a decision. The application will probably live for decades so we need to make a reversible decision with a framework that will be maintained for hopefully as long. I really like the static type check available with Guice, but not that the annotations bind explicitly to Guice instead of being external like in Spring. I also like that code appears to be more concise when using Guice as opposed to Spring. We need something that is robust and helpful. We do not need more than just DI at the moment. Is there a use case that definitive says go for one of these?
Edit 2011-07-27: The final decision was to use the JSR-330 API in code, and choose on a per-project basis if to use Spring, Guice or Weld. For stand-alone applications Guice has worked well so far as the JSR-330 implementation.
You can always use Spring Framework 2.5. It is a big one, but if you planning to use only DI you can use spring-core and spring-beans modules, which are pretty small (ca. 500KB and 300KB).
There is also Google Guice 2.0 which comes with a package with only basic stuff (no AOP) and it's 430KB.
Have you looked at the Google Guice framework? It's pretty lightweight and annotation-based, avoiding XML configuration files
There's also Pico- and Nano-container (from codehaus) which are quite lightweight although the last time I looked (admittedly a few years ago) the documentation was lacking.
I must say that I agree with others about what I assume is your presumption that Spring is massive and confusing. It's really a very simple IoC container and to be recommended.
There are a couple I know of you might find useful:
PicoContainer
Plexus (used in Maven)
I've found Plexus very useful in standalone apps as it has optional utility components for CLI interaction.
By "gigantic" I'm going to assume you're referring to Spring, but that's unfair, since you can cherry-pick the bits of Spring you want to use. If all you need is the IoC container, just use the appropriate JAR files and the appropriate bit of the API, and ignore the rest of it.
Most answers so far seem to be concerned with the size of the jar files to be added.
However I think the more important question is the impact on the project: How many lines of code must be added/changed in order to use the framework?
Even the "big" spring framework is actually very easy to use:
You basically need:
a xml file that describes your factories.
one line of code to initialize the container by loading the xml file
The nice thing is that spring is non-intrusive. So you do not have to implement specific interfaces or add any specific annotations or imports to your classes.
At best the single spot where you actually initialize the Spring container is the only
place in your application that has an actual dependency to spring classes.
I would strongly suggest to take a look at Spring ME. Although originally meant to be a way to use Spring on Java ME applications, it also works fine for standalone applications.
True, it doesn't give you all of the bells and whistles that Spring (Full) has to offer, but then again, Full Spring is much much more than a simple dependency injection framework.
On the plus side: it's based on a (compliant) subset of Spring's configuration files, and the footprint of the runtime is 0%. In fact, there isn't any. Spring ME will take your application context, and turn it into a class that has no dependencies on classes other than your own.
What's wrong with Spring?
These days it's packaged pretty well so you wouldn't need to take the whole kit and caboodle.
As an aside, I'm not a fan of the annotation based injection frameworks. This is because the annotations are bound to the class rather than the instance, the later being a pre-requisite, imho, for DI. This means every instance of a given class gets the same object(s) injected, which seems to defeat the point.
Also consider that DI doesn't even need a framework, what's wrong with your main method wiring together the application?
If you want something maximally simple and appropriate, then write some code that does what you want done. Presumably this involves wiring together factories based partly on fixed logic, and partly on run-time settings.
This has the advantage that the set of possible run-time configurations is known, and so documentable and testable.
It has the disadvantage that an deploying an unanticipated logic change inherently takes an extra second or so of compile time, and (more significantly) can't be sneaked into production without full testing by disguising it as 'just a configuration change'.
About a year ago I asked myself a question very like this. So I spend a few hours reading the Spring and Guice documentation. After about an hour with Spring I was left feeling that I could get a basic web app going, but had no idea how to use it in a stand alone application. After an hour with the Guice document everything had clicked and I could see just how I to do what I wanted to get done.
Now on to recommending Guice? Well no. What does your team already know? If someone already knows say Spring leaver that knowledge and have them spread it about. Like wise with Guice or Pico.
If you want something really light weight you might want to have a look at fuse it's fairly extendable so might be what you're looking for.
cheers
N