I have got the answers for setting up LdapContextSource and LdapTemplate without XML configurations from the SO question Best practice for configuring Spring LdapTemplate via annotations instead of XML?
What should be the annotation way for the below xml - automatically creating repository beans based on interfaces?
<ldap:repositories base-package="org.springframework.ldap.samples.useradmin.domain" />
Something like this.
#Configuration
#EnableLdapRepositories("org.springframework.ldap.samples.useradmin.domain")
public class LdapConfiguration { ... }
The #EnableLdapRepositories takes care of adding the correct configuration and scanning for repositories.
Related
I have a service that needs to use Neo4jRepository (regular repository provider by spring data).
public class SomeServiceBean<T>{
#Autowired
private Neo4jRepository<T,Long> Neo4jRepository;
}
This class will generate en error:
expected single matching bean but found 2: systemUserRepository,systemClaimRepository
The problem is that systemClaimRepository and systemUserRepository is extending Neo4jRepository<T,Long> as a bean without implementation.
Spring see systemClaimRepository and systemUserRepository as Neo4jRepository<T,Long> because they are extending it.
Is there anyway to inject Neo4jRepository<T,Long>?
Thanks
No how should this work?
You have two beans that match the interface and Spring does not know which implementation to inject.
I want to solve the following problem and need advice, what the best solution is.
I have a bundle A in which a service interface X is defined. A bundle B provides a service implementation of X and contributes the implementation to the tool. A and B use Google Guice and Peaberry to configure the setup of the objects.
There are two possibilities I can use to contribute the service implementation:
Using an eclipse extension:
In this solution I can use the GuiceExtensionFactory mechanism of Peaberry to create the service implementation using Guice and therefore can inject stuff needed by the implementation. The disadvantage here is that in the bundle defining the extension point, I need the boilerplate code for the resolution of the extensions because there is to my knowledge no way to get the extensions injected into the class which uses the extensions.
This looks like this:
<extension point="A.service.X">
<xservice
...
class="org.ops4j.peaberry.eclipse.GuiceExtensionFactory:B.XImpl"
.../>
</extension>
<extension
point="org.ops4j.peaberry.eclipse.modules">
<module
class="B.XModule">
</module>
</extension>
but I need the boilerplate code like this:
private List<X> getRegisteredX() {
final List<X> ximpls = new ArrayList<>();
for (final IConfigurationElement e : Platform.getExtensionRegistry().getConfigurationElementsFor( X_EXTENSION_POINT_ID)) {
try {
final Object object = e.createExecutableExtension("class"); //$NON-NLS-1$
if (object instanceof X) {
ximpls.add((X) object);
}
} catch (final CoreException ex) {
// Log
}
}
return ximpls;
}
Using an OSGI service:
My main problem here is to ensure that the service is registered. I want the bundle loaded lazily, so at least an access to one of the classes of the bundle is required. Registering the service programmatically using Peaberry has an issue, because nobody ever asks for a class of the bundle. The solution is to provide the service as a declarative service, but I do not know a way to create the service implementation in a way, that I can use Guice to inject required objects.
So I have some questions:
Is there something I do not know so far that implements the code needed to read the extensions at an extension point generically and allows to inject the extensions to the class using the extensions?
Is there a way to ensure that the service is provided even if it is added using the standard Peaberry mechanism, i.e., the bundle is activated when the service is requested?
Is there a way like the GuiceExtensionFactory for declarative services, so that the creation of the service implementation can be done by the injector of the bundle?
Something that look like:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Ximpl">
<implementation class="some.generic.guiceaware.ServiceFactory:B.Ximpl"/>
<service>
<provide interface="A.X"/>
</service>
</scr:component>
Summarized, I want a service implementation generated by Guice and I want to get the service implementations simply injected into the classes using the service without extensive boilerplate code. Has anybody a solution for that?
Sorry, to ask, but I searched the web for quite a while and so far I did not find a solution.
Thanks and best regards,
Lars
I found a solution, but since I did not find it without a lot of trying out and thinking I thought I share it here. From the options I mentioned in my posting, my solution uses the first one, that is Eclipse extension points and extensions. In order to use Guice in the context of extension points there are two aspects to consider:
Providing an extension that is created by an Guice injector
This is explained very well here: https://code.google.com/p/peaberry/wiki/GuiceExtensionFactory. There is one remark to make from my side. The creation of the extension object is done in an injector inside of the GuiceExtensionFactory, so it is an own context, which needs to be configured by the module given as additional extension to the factory. This can become an issue, if you have other needs that require creating the injector in the bundle on your own.
Defining an extension point so that the extensions are simply injected into the classes which use the extensions.
First thing to do is to define the extension point schema file as normally. It should contain the reference of an interface that has to be implemented by the extensions.
The id of the extension point has to be connected to the interface which is provided by the extensions and which is injected by guice/peaberry. Therefore peaberry provides an annotation to be used to annotate the interface:
import org.ops4j.peaberry.eclipse.ExtensionBean;
#ExtensionBean("injected.extension.point.id")
public interface InjectedInterface {
...
}
On some web pages you also find the information that if the id is equal to the qualified name of the interface, it can be found directly without the annotation but I did not try this out.
In order to enable the injection, you have to do two things to configure the Guice injector creation.
First the EclipseRegistry object of Peaberry has to be set as ServiceRegistry. Second the binding of the extension implementations to a provided service has to be done.
The injector creation has to be done in this way:
import org.osgi.framework.BundleContext;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.ops4j.peaberry.eclipse.EclipseRegistry;
import static org.ops4j.peaberry.Peaberry.*;
void initializer() {
Injector injector = Guice.createInjector(osgiModule(context, EclipseRegistry.eclipseRegistry()), new Module() {
binder.bind(iterable(InjectedInterface.class)).toProvider(service(InjectedInterface.class).multiple());
});
}
The extension implementations can then simply be injected like this:
private Iterable<InjectedInterface> registeredExtensions;
#Inject
void setSolvers(final Iterable<InjectedInterface> extensions) {
registeredExtensions = extensions;
}
With the described way it is possible to have injected extensions which are implemented by classes using Guice to get dependencies injected.
I did not find a solution to use osgi services so far, but perhaps there is someone who has an idea.
Best regards,
Lars
We are using flyweight pattern for some objects in our system. Those objects are also saved in database (mongodb). After loading the object back from db using Spring Data, there is no easy way to replace the object constructed by Spring Data with the object in the flyweight cache. For Java deserialization, there is readResolve() method. I wonder if Spring Data can add something similar to support this use case.
Is there any solutions with the current Spring Data implementation (1.4.1 release)?
They must have something otherwise enums wouldn't work either... I'd consider custom converters, e.g. here (look for the last section with PersonReadConverer):
http://docs.spring.io/spring-data/mongodb/docs/1.4.x/reference/html/mapping-chapter.html
I just hope it works when Person is a nested field inside another class - didn't get a chance to test it .
Good luck
Thanks #Pelit_Mamani for some suggestions. I did try to implement a converter and set it in mongo mapping converter and it seems to work. It works even when the object is embedded in other object.
<mongo:mapping-converter id="mappingConverter" base-package="com.mytest.domain" db-factory-ref="mongoDbFactory" disable-validation="true">
<mongo:custom-converters>
<mongo:converter>
<bean class="com.mytest.repo.converter.MyReadConverter" />
</mongo:converter>
</mongo:custom-converters>
</mongo:mapping-converter>
And the converter class:
public class MyReadConverter implements Converter<DBObject, MyObject>
I'm building a JAX-RS app that consists of a stockroom and a workplace. The stockroom holds a set of Java classes that can be instantiated (via AJAX) to create named instances of those classes in the workplace.
So far I'm able to reference the stockroom and workplace fine by declaring them as "singletons" in the RestEasy application
singletons.add(StockPlace.getInstance());
singletons.add(WorkPlace.getInstance());
I'm unable to understand how to understand how the stockroom content classes should be handled. The effect I'm trying to achieve is that when I dynamically create an instance of one of the stockroom classes, that instance can be dynamically accessed via REST commands. I've tried various permutations of:
classes.add(SomeComponent.class);
I think I'm missing knowledge of how the Java notion of how classes work as factories for making instances, and how both of these relate to what RestEasy calls classes, singletons (singletons ARE classes, yet RestEasy registers them as instances) and resources (instances?).
I suspect I'll wind up needing to dynamically register new instances but can't find a way to do that either. I did find a way to do it given the ServletContext, but am not able to get access to that either. Can someone get me on the right track?
Our eventual answer to this question was to bail out of RestEasy and convert to DropWizard. That problem and many others vanished and everything became easy again.
I believe I know what you are after, but I should at least give you a push in the right direction.
You will need to add the annotated RESTEasy class(es) to the registry. Below is the class I used for a recent project. It adds to the singletons (per what you did) but it also adds to the registry.
public class RESTEasyServerApplication extends javax.ws.rs.core.Application
{
// The RESTEasy registry
#Autowired
protected org.jboss.resteasy.spi.Registry registry;
// The annotated RESTEasy handler classes
private Set<Object> singletons = new HashSet<Object>();
private List<Object> handlers = new ArrayList<Object>();
public RESTEasyServerApplication()
{}
#Override
public Set<Object> getSingletons()
{
return singletons;
}
// Spring injection support
public void setHandlers( List<Object> handlers )
{
for( Object handler : handlers )
{
if( registry != null )
{
// Save a reference to the handler
this.handlers.add( handler );
// Register the handler with RESTEasy
registry.addSingletonResource( handler );
}
singletons.add( handler );
}
}
// Spring injection support
public List<Object> getHandlers()
{
return handlers;
}
}
I used Spring, and here is the relevant configuration:
<!-- RESTeasy/Spring integration -->
<import resource="classpath:springmvc-resteasy.xml" />
<!-- RESTeasy server application -->
<bean id="application" class="blah.blah.resteasy.RESTEasyServerApplication">
<property name="handlers">
<list>
<!-- Application specific handler classes -->
<ref bean="sample"/>
</list>
</property>
</bean>
Should be easy to modify/add a method to accept a single annotated RESTEasy class and make it work dynamically as required. The registry is defined in the springmvc-resteasy.xml file.
Since I've found no answers that don't involve strapping another whole layer of complexity (Spring) onto RestEasy, the solution I found livable is outlined in the final comment above. That is, don't rely on sending remote messages to instances unless the app is truly stateless (e.g. instances don't persist across messages). Only send remote messages to singletons which do persist across requests. Each such message can identify the desired instance (by String id in my case), and the singleton can forward to the identified instance as an ordinary POJO.
I still don't see why RestEasy unconditionally treats non-Singletons (instances) as ephemeral. Statelessness is not a restriction on REST, only a restriction on when GET methods can be used (idempotent calls). PUT and POST calls are neither stateless nor idempotent.
As I understand this, of course, and feel free to correct me. My focus is getting this app on the air, not exploring every corner of RestEasy, REST, and certainly not Spring.
I'm working in a Java project where I need to make automatically an application (ear file) multitenant. A minimum configuration (view here http://wiki.eclipse.org/EclipseLink/Development/Indigo/Multi-Tenancy) to enable multitenancy in a given entity is :
#Entity
#Table(name="EMP")
#Multitenant
public Employee() {
...
}
My goal is to add dynamically the #Multitenant annotation to all entities and my question is: is there a solution other that editing the bytecode to add this annotation?
Thanks in advance.
You could use an orm.xml if you don't want to change the code.
You could also use a SessionCustomizer to configure a MultitenantPolicy on each ClassDescriptor.