Spring.net ContextRegistry.GetContext fails with 2 interface implementations - dependency-injection

I have a .net application, that uses Spring.net.
Also there are 2 implementations of one interface. Which one should be used - it is based on configuration file.
The bootstrap for Spring has
<objects>
<object id="Impl1" name="Impl1" type="namespace.Impl1, IInterface" >
</object>
<object id="Impl2" name="Impl2" type="namespace.Impl2, IInterface" >
</object>
</objects>
It fails on
var appContext = ContextRegistry.GetContext();
The error message is:
An unhandled exception of type
'System.Configuration.ConfigurationErrorsException' occurred in
Spring.Core.dll
Additional information: Unsatisfied dependency expressed through
constructor argument with index 2 of type [namespace.IInterface] : No
unique object of type [namespace.IInterface] is defined : expected
single matching object but found 2:
System.Collections.Specialized.OrderedDictionary

I found another configuration, where autowire setting was set as autodetect.
<object id="workspaceExportService" type="namespace.Imp3, Namespace"
autowire="autodetect" />
This class Imp3 has a constructor with IInterface parameter. So, It tries to resolve the implementation of IInterface, but find two of them.
As a solution, you can add lazy-init="true" attribute to object node.

Related

JSF component object

There are many tutorials on the internet where component object on JSF page is used.
Usually component.clientId or component.valid are used.
Example
<h:inputText .... styleClass="#{component.valid ? '' : 'ui-input-invalid'}"/>
If i create page with such component, i get an error:
javax.el.PropertyNotFoundException:
The class 'javax.faces.component.UIPanel' does not have the property 'valid'.
I googled that for inputText should be there UIInput class (which has isValid method), but i have there UIPanel (which dasn't).
Any idea why is there UI Panel?
(Java EE 6, JSF 2.1, Weblogic 12.1.2)
Whether or not a single component is valid is irrelevant in the long run; the entire request will be marked as invalid, even if it's as a result of the failure of a single component.
You should be retrieving the status of a request on the facesContext implicit EL object
<h:inputText .... styleClass="#{facesContext.validationFailed ? '' : 'ui-input-invalid'}"/>
Nothing I've seen in the 2.1 or 2.2 API supports the the presence of a valid attribute for the component implicit EL object. It's an implementation of javax.faces.component.UIComponent
Reference:
UIComponent Javadoc

Context Initialization Parameters for Managed Bean

Background
A managed bean must have parameters configured through its web.xml file. The web.xml file defines context initialization parameters that are configured in JDeveloper (11.1.2.3) as follows:
The source for the definition of reporting.server.protocol follows:
<context-param>
<description>Defines the data transport mechanism to ret...</description>
<param-name>reporting.server.protocol</param-name>
<param-value>http</param-value>
</context-param>
The bean exposes public accessor methods for reportServerProtocol.
The source for the bean resembles:
#ManagedBean
#RequestScoped
public class OracleReportBean extends ReportBean {
#ManagedProperty("#{initParam['reporting.server.protocol']}")
private String reportServerProtocol = URLReportImpl.DEFAULT_PROTOCOL;
// ...
}
Problem
I would like to initialize the bean using context initialization parameters, rather than through FacesContext. In adfc-config.xml (note: not faces-confg.xml), some examples show references to initParam:
<managed-bean>
<managed-bean-name>reportBean</managed-bean-name>
<managed-bean-class>ca.corp.report.view.OracleReportBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>reportServerProtocol</property-name>
<property-class>java.lang.String</property-class>
<value>#{initParam['reporting.server.protocol']}</value>
</managed-property>
...
</managed-bean>
The key line being the value element #{initParam['reporting.server.protocol']}. However, JDeveloper shows the line as being incorrect. That is, the initParam context is not available within adfc-confing.xml.
The error is: "EL token initParam is unknown."
Question
Using an EL, how can the context initialization parameters be used to configure a managed bean, declaratively within ADFc?
Related Links
How to inject entire managed bean via #ManagedProperty annotation?
http://balusc.blogspot.ca/2011/09/communication-in-jsf-20.html
https://stackoverflow.com/tags/el/info
http://www.oracle.com/technetwork/developer-tools/adf/learnmore/43-remote-task-flow-169185.pdf
http://docs.oracle.com/cd/E25178_01/web.1111/b31974/taskflows_activities.htm
A bug in JDeveloper causes errors to be displayed:
However, even though the IDE displays an error, the code executes as expected.
In the ui layer you could try something like this :
<c:set target="${BeanName}" property="PropertyName" value="${true}"/>

Date conversion exception inside JSF composite component

When I access a JPA managed date value from JSF, it comes back with an javax.faces.component.UdateModelException saying
'Cannot convert 01.01.10 00:00 of type class java.util.Date to class org.apache.openjpa.util.java$util$Date$proxy
Using a JPA-managed date value (which means it is proxied) works fine when it is used directly from the EL likes this:
'<h:outputLabel value="MyDateValue" for="input"/>
'<h:inputText id="inputDate" value="#{bean.myDate}"/>
However, it causes trouble when trying to use it with composite components
and gives back the following converter exception and thus can't update the model...
The (simplified) JSF composite component inputDate.xhtml
<head>
<title>A date input field</title>
</head>
<composite:interface>
<composite:attribute name="dateValue"/>
</composite:interface>
<composite:implementation>
<h:outputLabel value="MyDateValue" for="input"/>
<h:inputText id="input" value="#{cc.attrs.dateValue}"/>
</composite:implementation>
Assumption:
It seems the proxy replacement in OpenJPA is handled differently when the value is being accessed from inside a composite. My guess is the EL-resolver handles calls to object values differently when it is passed to composites. Passing it to composites means it is first accessed within the composite, which is too late and the required replacement of the proxy is not accomplished (thus the converter exception)
So I tried to change the Expression Language for MyFaces, but it didn't work in Websphere, even though I changed the class loading to parent last and provided el-impl and el-api from glassfish in the lib folder and inserted the necessary context-param for MyFaces
How do you guys use JPA-managed dates (or other proxied entities) in composite components???
If you are using the sun EL implementation you might use the following ELResolver which works around this issue:
public class BugfixELResolver extends ELResolver {
//...
#Override
public Class<?> getType(ELContext anElContext, Object aBase, Object aProperty) {
if (aBase.getClass().getCanonicalName().equals("com.sun.faces.el.CompositeComponentAttributesELResolver.ExpressionEvalMap")){
Object tempProperty=((Map)aBase).get(aProperty);
if (tempProperty!=null&&tempProperty.getClass().getCanonicalName().equals("org.apache.openjpa.util.java.util.Date.proxy")) {
anElContext.setPropertyResolved(true);
return java.util.Date.class;
}
}
return null;
}
}
Add it to the faces-config this way:
<el-resolver>
xxx.BugfixELResolver
</el-resolver>
This workaround can also be used in environments where you can not change the EL implementation (like websphere etc.).
Here is the workaround. The problem seems to be WebSpheres' ExpressionLanguage Implementation or rather the order resolvers are executed. Registering the JBoss EL implementation works and resolves the date proxies before calling the composite component. I also tried the Glassfish EL, but it didn't work either...
Registering a alternative EL is quite strange: The setting in web.xml for MyFaces is
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Additionally under WebContent/META-INF/services/ a file named javax.el.expressionFactory is needed with this single line org.jboss.el.ExpressionFactoryImpl. The class comes from jboss-el-2.0.2.CR1.jar
(sorry, couldn't find the link to a maven repo)
I will keep you updated once I find a better solution...

Inject a String into a Message Driven Bean

I want to configure the behaviour of one of my mdbs with string. i created a setMessageType method and want to inject the identifier string into the mdb by configuration in the ejb-jar (deployment descriptor).
I know how do declare a bean in the ejb-jar but how do i control dependency injection?
Greetings,
Laures
funny i never go an answer to this questions.
<message-driven>
<ejb-name>mymdb</ejb-name>
<ejb-class>net.something.MyMDBClass</ejb-class>
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Topic</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destination</activation-config-property-name>
<activation-config-property-value>i.listen.here</activation-config-property-value>
</activation-config-property>
</activation-config>
<env-entry>
<env-entry-name>MessageType</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>myconfigstring</env-entry-value>
</env-entry>
</message-driven>

Unity and Object Creation

I am using unity as my IoC container. I am trying to implement a type of IProviderRepository. The concrete implementation has a constructor that accepts a type of IRepository. When I remove the constructor parameter from the concrete implementation everything works fine. I am sure the container is wired correctly. When I try to create the concrete object with the constructor I receive the following error:
"The current build operation (build key Build Key[EMRGen.Infrastructure.Data.IRepository1[EMRGen.Model.Provider.Provider], null]) failed: The current type, EMRGen.Infrastructure.Data.IRepository1[EMRGen.Model.Provider.Provider], is an interface and cannot be constructed. Are you missing a type mapping? (Strategy type BuildPlanStrategy, index 3)".
Is it possible to achieve the above mention functionality with Unity? Namely have Unity infer a concrete type from the Interface and also inject the constructor of the concrete type with the appropriate concrete object based on constructor parameters. Below is sample of my types defined in Unity and a skeleton class listing for what I want to achieve. IProviderRepository is implemented by ProviderRepository which has a constructor that expects a type of IRepository.
<typeAlias alias="ProviderRepositoryInterface" type="EMRGen.Model.Provider.IProviderRepository, EMRGen.Model" />
<typeAlias alias="ProviderRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.Providers.ProviderRepository, EMRGen.Infrastructure.Repositories" />
<typeAlias alias="ProviderGenericRepositoryInterface" type="EMRGen.Infrastructure.Data.IRepository`1[[EMRGen.Model.Provider.IProvider, EMRGen.Model]], EMRGen.Infrastructure" />
<typeAlias alias="ProviderGenericRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.EntityFramework.ApplicationRepository`1[[EMRGen.Model.Provider.Provider, EMRGen.Model]], EMRGen.Infrastructure.Repositories" />
<!-- Provider Mapping-->
<typeAlias alias="ProviderInterface" type="EMRGen.Model.Provider.IProvider, EMRGen.Model" />
<typeAlias alias="ProviderConcrete" type="EMRGen.Model.Provider.Doctor, EMRGen.Model" />
Illustrate the call being made inside my class:
public class PrescriptionService
{
PrescriptionService()
{
IUnityContainer uc = UnitySingleton.Instance.Container;
UnityServiceLocator unityServiceLocator = new UnityServiceLocator(uc);
ServiceLocator.SetLocatorProvider(() => unityServiceLocator);
IProviderRepository pRepository =
ServiceLocator.Current.GetInstance<IProviderRepository>();
}
}
public class GenericRepository<IProvider> : IRepository<IProvider>
{
}
public class ProviderRepository : IProviderRepository
{
private IRepository<IProvider> _genericProviderRepository;
//Explict public default constructor
public ProviderRepository(IRepository<IProvider> genericProviderRepository)
{
_genericProviderRepository = genericProviderRepository;
}
}
What you want to do is possible, but you need to tell Unity how to map from interfaces to concrete types. AFAICT, your current configuration registers a lot of types, but doesn't specify how they relate to each other.
That said, static Service Locator is an anti-pattern. Consider changing your code to use proper Constructor Injection instead. That would also simplify your code considerably:
public class PrescriptionService
{
private readonly IProviderRepository pRepository;
public PrescriptionService(IProviderRepository pRepository)
{
if (pRepository == null)
{
throw new ArgumentNullException("pRepository");
}
this.pRepository = pRepository;
}
}
Using Unity, you would be able to wire it up like this:
var container = new UnityContainer();
container.RegisterType<PrescriptionService>();
container.RegisterType<IProviderRepository, ProviderRepository>();
container.RegisterType<IRepository<IProvider>, MyRepository<IProvider>>();
var ps = container.Resolve<PrescriptionService>();
Configure the container and resolve all components in the application's Composition Root.
You should only use XML configuration if you need to be able to change certain components without recompiling your application.

Resources