I am working on a project that uses dropwizard's hibernate bundle to get a session factory per the below docs:
http://www.dropwizard.io/0.7.1/docs/manual/hibernate.html
The project doesn't use any xml and only uses annotated classes for the configuration of the bundle just like in the example.
public class ExampleConfiguration extends Configuration {
#Valid
#NotNull
#JsonProperty("database")
private DataSourceFactory database = new DataSourceFactory();
public DataSourceFactory getDataSourceFactory() {
return database;
}
}
private final HibernateBundle<ExampleConfiguration> hibernate =
new HibernateBundle<ExampleConfiguration>(
some.class
) {
#Override
public DataSourceFactory getDataSourceFactory(ExampleConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
However, we have a use case where I need to prepend the environment to the table name of the DAO objects such that the #Table annotation gets overwritten.
I have a class which implements ImprovedNamingStrategy, per the below docs
http://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/cfg/ImprovedNamingStrategy.html
But how do I hook the naming strategy into my dropwizard hibernate bundle. I would like to be able to do something like this...
hibernateBundle.setNamingStrategy(ImprovedNamingStrategy.Instance)
or
hibernateBundle.addAnnotatedClass(someHibernateNamingPropertyConfig)
https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/cfg/Configuration.html#setNamingStrategy(org.hibernate.cfg.NamingStrategy)
However, the hibernateBundle API doesn't allow for any of this.
Looking through the source code of HibernateBundle
https://github.com/dropwizard/dropwizard/blob/master/dropwizard-hibernate/src/main/java/io/dropwizard/hibernate/HibernateBundle.java
You can see that it uses "import io.dropwizard.Configuration;" as opposed to org.hibernate.cfg which does expose all of these methods. I'm trying to avoid a major refactor so if there is a "hacky" way to force set the naming property on the bundle, then I'm okay with that.
Any ideas of where to go from here would be much appreciated.
Found a solution for this that works for me in Dropwizard 0.8.4. Not sure if it can help you with Dropwizard 0.7.1, but it will definitely be helpful for readers coming from Google with the same question.
You can extend HibernateBundle and override configure(). This method is called just before SessionFactoryFactory is going to be built, with the Configuration object for it. You can then override the method to add any special configurations you might need.
Example:
public abstract class DatabaseWithImprovedNamingStrategyBundle extends ScanningHibernateBundle {
public DatabaseWithImprovedNamingStrategyBundle(String pckg) {
super(pckg);
}
#Override
protected void configure(Configuration configuration) {
super.configure(configuration);
configuration.setNamingStrategy(ImprovedNamingStrategy.INSTANCE);
}
}
This example uses ScanningHibernateBundle because it's the one I was using, but you can use HibernateBundle directly too.
I just decided not to use the Hibernate Bundle and create a second config object which reads values out of the Hibernate Bundle.
Related
I'm trying to understand how to handle conditionally creating new instances of a class that uses #Inject. In the below example I have a factory that instantiates classes based on a parameter.
AnimalFactory does not have access to the injector the main class of my application has, so I can't use injector.getInstance(Cat.class)
class AnimalFactory {
public IAnimal create(AnimalType type) {
if (type.equals(AnimalType.CAT)) {
return new Cat(); // Cat uses #Inject, so this won't work of course. But ???
} else if (type.equals(AnimalType.DOG)) {
return new Dog();
}
}
}
In the rest of my app, classes are injected into my constructors because I always need them. Guice creates an instance/singleton for each. But in this scenario, I do not want to create and inject instances for each animal because all but one are needed.
You can use a MapBinder as described here:
public class AnimalModule extends AbstractModule {
public void configure() {
MapBinder<AnimalType, IAnimal> animalBinder= MapBinder.newMapBinder(binder(), AnimalType.class, IAnimal.class);
animalBinder.addBinding(AnimalType.DOG).to(Dog.class);
...
}
}
And than use it in your factory:
class AnimalFactory {
#Inject
Map<AnimalType, IAnimal> animals;
public IAnimal create(AnimalType type) {
return animals.get(type);
}
}
Actually I worked on exactly the same issue and I wrote a feature that allows you to create self-populating factory. Meaning that if you work in Spring/Spring-boot environment you can create a factory that can access and provide any interface implementing class that is managed by Spring-boot without injecting in the factory. You can also give the instances custom names. So, it seems like it fits your case exactly. Here is a link to an article that describes the feature in great detail: Non-intrusive access to "Orphaned" Beans in Spring framework. Also, in MgntUtils library Javadoc there is a good description of the feature here enter link description here. The library itself including source code could be found on Github here and in the package com.mgnt.lifecycle.management.example there is a working example. Maven artifacts are here
Is it possible to configure a bean in such a way that it wont be used by a group of profiles? Currently I can do this (I believe):
#Profile("!dev, !qa, !local")
Is there a neater notation to achieve this? Let's assume I have lots of profiles. Also, if I have a Mock and concrete implementation of some service (or whatever), Can I just annotate one of them, and assume the other will be used in all other cases? In other words, is this, for example, necessary:
#Profile("dev, prof1, prof2")
public class MockImp implements MyInterface {...}
#Profile("!dev, !prof1, !prof2") //assume for argument sake that there are many other profiles
public class RealImp implements MyInterface {...}
Could I just annotate one of them, and stick a #Primary annotation on the other instead?
In essence I want this:
#Profile("!(dev, prof1, prof2)")
Thanks in advance!
Since Spring 5.1 (incorporated in Spring Boot 2.1) it is possible to use a profile expression inside profile string annotation (see the description in Profile.of(..) for details).
So to exclude your bean from certain profiles you can use an expression like this:
#Profile("!dev & !prof1 & !prof2")
Other logical operators can be used as well, for example:
#Profile("test | local")
Short answer is: You can't in versions of Spring prior to Spring 5.1 (i.e. versions of Spring Boot prior to 2.1).
But there is a neat workarounds that exists thanks to the #Conditional annotation.
Create Condition matchers:
public static abstract class ProfileCondition extends SpringBootCondition {
#Override
public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
if (matchProfiles(conditionContext.getEnvironment())) {
return ConditionOutcome.match("A local profile has been found.");
}
return ConditionOutcome.noMatch("No local profiles found.");
}
protected static abstract boolean matchProfiles(final Environment environment);
}
public class DevProfileCondition extends ProfileCondition {
protected boolean matchProfiles(final Environment environment) {
return Arrays.stream(environment.getActiveProfiles()).anyMatch(prof -> {
return prof.equals("dev") || prof.equals("prof1") || prof.equals("prof2");
});
}
}
public static class ProdProfileCondition extends ProfileCondition {
protected boolean matchProfiles(final Environment environment) {
return Arrays.stream(environment.getActiveProfiles()).anyMatch(prof -> {
return (!prof.equals("dev") && !prof.equals("prof1") && !prof.equals("prof2"));
});
}
}
Use it
#Conditional(value = {DevProfileCondition.class})
public class MockImpl implements MyInterface {...}
#Conditional(value = {ProdProfileCondition.class})
public class RealImp implements MyInterface {...}
However, this aproach requires Springboot.
From what I understand, what you want to do is be capable of replacing some of your beans with some stub/mock beans for specific profiles. There are 2 ways to address this:
Exclude the not needed beans for the corresponding profiles and include by default everything else
Include only the required beans for each profile
The first option is feasible but difficult. This is because the default behaviour of Spring when providing multiple profiles in #Profile annotation is an OR condition (not an AND as you would need in your case). This behaviour of Spring is the more intuitive, because ideally each profile should correspond to each configuration of your application (production, unit testing, integration testing etc.), so only one profile should be active at each time. This is the reason OR makes more sense than AND between profiles. As a result of this, you can work around this limitation, probably by nesting profiles, but you would make your configuration very complex and less maintainable.
Thus, I suggest you go with the second approach. Have a single profile for each configuration of your application. All the beans that are the same for every configuration can reside in a class that will have no #Profile specified. As a result, these beans will be instantiated by all the profiles. For the remaining beans that should be distinct for each different configuration, you should create a separate #Configuration class (for each Spring profile), having all of them with the #Profile set to the corresponding profile. This way, it will be really easy to tract what is injected in every case.
This should be like below:
#Profile("dev")
public class MockImp implements MyInterface {...}
#Profile("prof1")
public class MockImp implements MyInterface {...}
#Profile("prof2")
public class MockImp implements MyInterface {...}
#Profile("the-last-profile") //you should define an additional profile, not rely on excluding as described before
public class RealImp implements MyInterface {...}
Last, #Primary annotation is used to override an existing beans. When there are 2 beans with the same type, if there is no #Primary annotation, you will get an instantiation error from Spring. If you define a #Primary annotation for one of the beans, there will be no error and this bean will be injected everywhere this type is required (the other one will be ignored). As you see, this is only useful if you have a single Profile. Otherwise, this will also become complicated as the first choice.
TL;DR: Yes you can. For each type, define one bean for each profile and add a #Profile annotation with only this profile.
I'm trying to develop a simple application using OSGi framework. My question involves an "utility bundle" available in the framework: let me explain with a pretty verbose example. At the moment I'm trying to build an event my bundle will send.
From what I understood, what i need is to do something like the following (event admin felix):
public void reportGenerated(Report report, BundleContext context)
{
ServiceReference ref = context.getServiceReference(EventAdmin.class.getName());
if (ref != null)
{
EventAdmin eventAdmin = (EventAdmin) context.getService(ref);
Dictionary properties = new Hashtable();
properties.put("title", report.getTitle());
properties.put("path" , report.getAbsolutePath());
properties.put("time", System.currentTimeMillis());
Event reportGeneratedEvent = new Event("com/acme/reportgenerator/GENERATED", properties);
eventAdmin.sendEvent(reportGeneratedEvent);
}
}
Now, since an OSGi application may have lots of bundles, I thought to create a subclass of Event for every bundle (eg. I have a bundle named "BundleExample"? Inside it's exported classes there will be a "BundleExampleEvent"). I know this doesn't add any information since you can know which event you received by looking at "topic", but please bear with me for the moment.
Now, the Event constructor needs a topic and a Map<String, Object>. However, to "simplify" the event constructor, I would like to have only the topic and the list of parameters to put inside the map. For example here's what might be a BundleExampleEvent class:
public class BundleExampleEvent extends Event{
private int importantVariable;
public BundleExampleEvent(String topic, int importantVariable) {
super(topic, Utils.toMap("importantVariable", importantVariable));
//here toMap is static
}
public int getImportantVariable() {
return this.importantVariable;
}
}
Ok, please note the Utils.toMap: it's a function that allows you to convert a sequence of String, Object into a Map. Ok, now Utils is an example of a utility class (stupid, useless but a utility class nonetheless). In the spirit of OSGi I want to make this utility class a bundle as well: my thought would be to start this Utils bundle at framework boot and then whenever I need one of its utility I want to fetch a reference via #Reference annotation.
This can work greatly in any bundle interface implementation, like this:
#Component
public class BundleExampleImpl implements BundleExample {
#Reference
private Utils utils;
#Override
public String sayHello() {
return this.utils.fetchHello();
//another useless utility function, but hopefully it conveys what i'm trying to do
}
}
But what about other classes (i.e. called by BundleExampleImpl during its work)? For example what about the BundleExampleEvent? I need to call it from sayHello method and I want to use this utility also inside that class in order to compute the Map! In the previous example i used a static function, but I would like to use the reference of Utils OSGi gave me.
Of course I could add a parameter inside the constructor of BundleExampleEvent in order to satisfy the link but I rather not to do it because it's pretty silly that something would depend on an "utility class"; my question are:
Is this the only method available if I want a "utility bundle"?
Or can I do something weird like adding a reference of Utils also in my BundleExampleEvent; i.e. something like this:
public class BundleExampleEvent extends Event{
#Reference
private Utils utils;
private int importantVariable;
public BundleExampleEvent(String topic, int importantVariable) {
super(topic, Utils.toMap("importantVariable", importantVariable));
//here toMap is static
}
public int getImportantVariable() {
return this.importantVariable;
}
}
Or maybe the whole idea of having an "utility bundle" is just pure trash?
Thanks for any reply. Hope I could convey my problem in the clearest way
I don't think there is any point in Utils being a service. Things should only be a service if they can conceivably have multiple implementations. In your case, the consumer of the Util functionality only ever wants a single implementation... the implementation is the contract.
I don't even think the utils code should be in a bundle. Just make it into a library that is statically linked into the bundles that need it.
In your case the Utils utils would be an OSGi service. Then you want to use this service inside an object that is not a service like BundleExampleEvent.
What you could do is to create a service that creates BundleExampleEvent instances and feeds it with an OSGi service. Kind of like a factory as a service. The problem with this is that services in OSGi are dynamic. If the service needed by the BundleExampleEvent instance goes away then the object would have to be discarded. So this only works for short lived objects.
In the eventadmin example a different solution would be to not use a special event class but instead create a service that has a method to send such an event. Then all the magic would happen inside this method and the result would be an event without further logic. You could also inject EventAdmin into that service using DS.
This works very well in OSGI but has the disadvantage of the anemic domain model (http://www.martinfowler.com/bliki/AnemicDomainModel.html).
I am not sure which variant to prefer.
Can I do it with reflection or something like that?
I have been searching for a while and there seems to be different approaches, here is a summary:
reflections library is pretty popular if u don't mind adding the dependency. It would look like this:
Reflections reflections = new Reflections("firstdeveloper.examples.reflections");
Set<Class<? extends Pet>> classes = reflections.getSubTypesOf(Pet.class);
ServiceLoader (as per erickson answer) and it would look like this:
ServiceLoader<Pet> loader = ServiceLoader.load(Pet.class);
for (Pet implClass : loader) {
System.out.println(implClass.getClass().getSimpleName()); // prints Dog, Cat
}
Note that for this to work you need to define Petas a ServiceProviderInterface (SPI) and declare its implementations. you do that by creating a file in resources/META-INF/services with the name examples.reflections.Pet and declare all implementations of Pet in it
examples.reflections.Dog
examples.reflections.Cat
package-level annotation. here is an example:
Package[] packages = Package.getPackages();
for (Package p : packages) {
MyPackageAnnotation annotation = p.getAnnotation(MyPackageAnnotation.class);
if (annotation != null) {
Class<?>[] implementations = annotation.implementationsOfPet();
for (Class<?> impl : implementations) {
System.out.println(impl.getSimpleName());
}
}
}
and the annotation definition:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PACKAGE)
public #interface MyPackageAnnotation {
Class<?>[] implementationsOfPet() default {};
}
and you must declare the package-level annotation in a file named package-info.java inside that package. here are sample contents:
#MyPackageAnnotation(implementationsOfPet = {Dog.class, Cat.class})
package examples.reflections;
Note that only packages that are known to the ClassLoader at that time will be loaded by a call to Package.getPackages().
In addition, there are other approaches based on URLClassLoader that will always be limited to classes that have been already loaded, Unless you do a directory-based search.
What erickson said, but if you still want to do it then take a look at Reflections. From their page:
Using Reflections you can query your metadata for:
get all subtypes of some type
get all types annotated with some annotation
get all types annotated with some annotation, including annotation parameters matching
get all methods annotated with some
In general, it's expensive to do this. To use reflection, the class has to be loaded. If you want to load every class available on the classpath, that will take time and memory, and isn't recommended.
If you want to avoid this, you'd need to implement your own class file parser that operated more efficiently, instead of reflection. A byte code engineering library may help with this approach.
The Service Provider mechanism is the conventional means to enumerate implementations of a pluggable service, and has become more established with the introduction of Project Jigsaw (modules) in Java 9. Use the ServiceLoader in Java 6, or implement your own in earlier versions. I provided an example in another answer.
Spring has a pretty simple way to acheive this:
public interface ITask {
void doStuff();
}
#Component
public class MyTask implements ITask {
public void doStuff(){}
}
Then you can autowire a list of type ITask and Spring will populate it with all implementations:
#Service
public class TaskService {
#Autowired
private List<ITask> tasks;
}
The most robust mechanism for listing all classes that implement a given interface is currently ClassGraph, because it handles the widest possible array of classpath specification mechanisms, including the new JPMS module system. (I am the author.)
try (ScanResult scanResult = new ClassGraph().whitelistPackages("x.y.z")
.enableClassInfo().scan()) {
for (ClassInfo ci : scanResult.getClassesImplementing("x.y.z.SomeInterface")) {
foundImplementingClass(ci); // Do something with the ClassInfo object
}
}
With ClassGraph it's pretty simple:
Groovy code to find implementations of my.package.MyInterface:
#Grab('io.github.classgraph:classgraph:4.6.18')
import io.github.classgraph.*
new ClassGraph().enableClassInfo().scan().withCloseable { scanResult ->
scanResult.getClassesImplementing('my.package.MyInterface').findAll{!it.abstract}*.name
}
What erikson said is best. Here's a related question and answer thread - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html
The Apache BCEL library allows you to read classes without loading them. I believe it will be faster because you should be able to skip the verification step. The other problem with loading all classes using the classloader is that you will suffer a huge memory impact as well as inadvertently run any static code blocks which you probably do not want to do.
The Apache BCEL library link - http://jakarta.apache.org/bcel/
Yes, the first step is to identify "all" the classes that you cared about. If you already have this information, you can enumerate through each of them and use instanceof to validate the relationship. A related article is here: https://web.archive.org/web/20100226233915/www.javaworld.com/javaworld/javatips/jw-javatip113.html
Also, if you are writing an IDE plugin (where what you are trying to do is relatively common), then the IDE typically offers you more efficient ways to access the class hierarchy of the current state of the user code.
I ran into the same issue. My solution was to use reflection to examine all of the methods in an ObjectFactory class, eliminating those that were not createXXX() methods returning an instance of one of my bound POJOs. Each class so discovered is added to a Class[] array, which was then passed to the JAXBContext instantiation call. This performs well, needing only to load the ObjectFactory class, which was about to be needed anyway. I only need to maintain the ObjectFactory class, a task either performed by hand (in my case, because I started with POJOs and used schemagen), or can be generated as needed by xjc. Either way, it is performant, simple, and effective.
A new version of #kaybee99's answer, but now returning what the user asks: the implementations...
Spring has a pretty simple way to acheive this:
public interface ITask {
void doStuff();
default ITask getImplementation() {
return this;
}
}
#Component
public class MyTask implements ITask {
public void doStuff(){}
}
Then you can autowire a list of type ITask and Spring will populate it with all implementations:
#Service
public class TaskService {
#Autowired(required = false)
private List<ITask> tasks;
if ( tasks != null)
for (ITask<?> taskImpl: tasks) {
taskImpl.doStuff();
}
}
I'm working with a Guice enabled framework.
When using classes that were created by the framework (or subclasses that override existing bindings), I can instantiate framework provided variables very easily. Whatever I need, it's just a matter of
#Inject
FrameworkProvidedType variable;
However, in my custom created classes, that doesn't work. All of the injected variables are null.
It's my understanding that in order to use injection, my class has to have a binding.
If I'm subclassing an existing framework class, I can override the binding in my module class. That's pretty straightforward.
But I have a new class and I don't know how to bind it to the underlying framework.
public Class myCustomClass {
private String iNeedthis;
private Context thisToo;
#Inject
FrameWorkThing magic;
public myCustomClass(String iNeedThis, Context thisToo){
this.iNeedThis = iNeedThis;
this.thisToo = thisToo;
}
public void DoMagic(){
//null pointer error because magic was not injected
magic.doMagic(this.iNeedthis);
}
}
How do I Guice-enable this new class?
I tried this in my Runtime Module
public Class<myCustomClass> bindMyCustomClass(){
return MyCustomClass.class;
}
and failed miserably.
No thanks to #bmorris591 who dismissed and downvoted the question out of the gate, I found an answer.
#Inject-ing a field into a class means that the class instance needs to be created by Guice.
Step 1 is creating a factory for the class. This may not be necessary, but it worked for me.
public interface MyCustomClassFactory {
public MyCustomClass create(String iNeedThis, Context thisToo);
}
Step 2 is installing the factory into Guice
#Override
public void configure(Binder binder) {
super.configure(binder);
binder.install(new FactoryModuleBuilder().build(MyCustomClass.class));
}
In my particular case - the framework I'm working with provides a Module class that is an implementation of com.google.inject.Module.
Within that class is a "configure(Binder binder)" function that is called on startup.
Step 3 is actually annotating the constructor
#Inject
public myCustomClass(String iNeedThis, Context thisToo){
this.iNeedThis = iNeedThis;
this.thisToo = thisToo;
}
Useful and related web page that put me on the right track:
http://beust.com/weblog/2012/08/21/advanced-dependency-injection-with-guice/
This talks about assisted injection, but it gave enough information and a simple enough to understand example that taking the next step was pretty easy.