Context lookup for EJB client returns $Proxy119 object instead of actual class object - jboss

I am simply invoking a EJB 3.0 like this in JBoss:
MyEJB myEJB = (MyEJB) initialContext.lookup("");
Now the lookup works fine. The object returned has the viewType,moduleName, beanName as expected. But it throws this exception:
2015-04-10 18:49:08,266 ERROR [org.teiid.CONNECTOR] (Worker0_QueryProcessorQueue1128) Connector worker process failed for atomic-request=GfxN/Obks1QK.1.1.0: java.lang.ClassCastException: com.sun.proxy.$Proxy119 cannot be cast to com.MyEJB
How do I cast it to the object that I intend to use?

here's a sample example of code :
HelloLocalHome helloHome;
HelloLocal hello;
//In your main or init method,
// 1. Retreive the Home Interface using a JNDI Lookup
// Retrieve the initial context for JNDI.
// No properties needed when local
Context context = new InitialContext();
// Retrieve the home interface using a JNDI lookup using
// the java:comp/env bean environment variable
// specified in web.xml
helloHome = (HelloLocalHome) context.lookup("java:comp/env/ejb/HelloBean");
//2. Narrow the returned object to be an HelloHome object.
// Since the client is local, cast it to the correct object type.
//3. Create the local Hello bean instance, return the reference
hello = (HelloLocal)helloHome.create();
//And the call will be as follows :
hello.sayHello("James Earl")

It turns out the correct way to do that is this:
StatelessEJBLocator<MyEjb> locator = new StatelessEJBLocator(
MyEjb.class, APP_NAME, MODULE_NAME,
MyEjbRemote.class.getSimpleName(), DISTINCT_NAME);
MyEjb myEjb = org.jboss.ejb.client.EJBClient.createProxy(locator);

Related

WildFly naming subsystem: how to bind to a java.util.Properties object

I intend to define a JNDI propery of the type java.util.Properties in the WildFly application server to read it from my application.
As described in the an older WildFly documentation one can create a global binding of the type object-factory. In the example is an optional environment tag to hold multiple key/value pairs. That would map exactly my desire to get a java.util.Properties when reading a JNDI resource.
The question is weather there is already an implementiation of javax.naming.spi.ObjectFactory to create a java.util.Properties object out of an object-factory binding or do I need to implement it myself and install it as a separate module (like it is described at mastertheboss.com/...)?
Ok, I just implemented it mysef.
package com.myorg.wildfly.objectfactory;
...
public class WildFlyPropertiesObjectFactory implements ObjectFactory
{
#Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception
{
Properties p = new Properties();
if(environment != null)
{
Set<?> keySet = environment.keySet();
for(Object key : keySet)
{
p.put(key, environment.get(key));
}
}
return p;
}
}
Clean&Build this single class into a JAR file wildfly-properties-objetfactory.jar
Add a module via jboss-cli.sh
module add --name=my.jndi.propertyreader --resource=wildfly-properties-objetfactory.jar --dependencies=javax.api
Create a naming binding via jboss-cli.sh
/subsystem=nameing/binding=java\:\/my_super_cool_jndi_name:add(binding-type=object-factory, module=my.jndi.propertyreader, class=com.myorg.wildfly.objectfactory.WildFlyPropertiesObjectFactory, environment=[key1=value1, key2=value2])
And in my application I can access it in an CDI bean via
public void test() {
Properties p = (Properties) new InitialContext().lookup("java:/my_super_cool_jndi_name");
System.out.printf("Properties: %s%n", p);
}
Or as shown in the mentioned link inject it as a direct dependency #Resource(lookup = "java:/my_super_cool_jndi_name") Properties p;
Works as a charm.

An exception of using dozer to copy data from map to java bean

I want to copy data from map(request.getParameterMap()) to java bean. For example:
Map<String,Object> map = new HashMap<>();
map.put("payment_code", "1420956468542a2");
//...
public class PaymentLogDTO {
#Mapping("payment_code")
private String paymentCode;
//...
}
but when I execute map method in unit test,
DozerBeanMapper dozer = new DozerBeanMapper();
dozer.map(map, PaymentLogDTO.class);
it failed. The exception message is:
org.dozer.MappingException: No such field found java.util.HashMap.payment_code
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:322)
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:320)
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:320)
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:309)
at org.dozer.propertydescriptor.FieldPropertyDescriptor$ChainedPropertyDescriptor.<init>(FieldPropertyDescriptor.java:104)
at org.dozer.propertydescriptor.FieldPropertyDescriptor.<init>(FieldPropertyDescriptor.java:51)
at org.dozer.propertydescriptor.PropertyDescriptorFactory.getPropertyDescriptor(PropertyDescriptorFactory.java:64)
at org.dozer.fieldmap.FieldMap.getSrcPropertyDescriptor(FieldMap.java:385)
at org.dozer.fieldmap.FieldMap.getSrcFieldValue(FieldMap.java:86)
at org.dozer.MappingProcessor.mapField(MappingProcessor.java:294)
at org.dozer.MappingProcessor.map(MappingProcessor.java:267)
at org.dozer.MappingProcessor.mapToDestObject(MappingProcessor.java:216)
at org.dozer.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:196)
at org.dozer.MappingProcessor.mapGeneral(MappingProcessor.java:170)
at org.dozer.MappingProcessor.map(MappingProcessor.java:104)
at org.dozer.MappingProcessor.map(MappingProcessor.java:99)
at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:120)
at org.springside.modules.mapper.BeanMapper.map(BeanMapper.java:36)
Is there any method can solve this problem? That is I don't need to create a java bean using the same name of query paramter name as it's properties' names.
The #Mapping annotation tells the source/destination field, it has nothing related to the Map class...
So with #Mapping("payment_code"), it looks for a field "payement_code", and not for an element in your map collection.

Entity Framework - Database First without config

I'm developing a class library that deals with an exiting db using EF. I want to avoid the consumer of the class library (and .exe or a web site) to have in the *.config file the Entity connection string. I want the connection string set a run-time.
How do I set the connection string with Database First approach? There is no constructor overload that takes a connection string and when I created one (in a separate partial class) I got an "UnintentionalCodeFirstException".
I have reviewed already the following links:
Is there a way to change connection string in database first?. Its about modifying the connection string in the config file, which I want to avoid, also because it would recycle the process (in the case of a web app)
How can l use Entity Framework without App.config. Not good because it uses ObjectContext and I need the context generated when I imported the database.
There is a constructor on DbContext that takes a DbConnection, and you need to use an EntityConnection object for it:
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
// Set the properties for the data source.
sqlBuilder.DataSource = "server name";
sqlBuilder.InitialCatalog = "database name";
sqlBuilder.IntegratedSecurity = true;
// Build the SqlConnection connection string.
string providerString = sqlBuilder.ToString();
var entityBuilder = new EntityConnectionStringBuilder();
// Initialize the EntityConnectionStringBuilder.
//Set the provider name.
entityBuilder.Provider = "System.Data.SqlClient";
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = providerString;
// Set the Metadata location.
entityBuilder.Metadata = #"res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl";
using(var context = new YourDbContext(entityBuilder.ToString())){
//do stuff here
}
The important thing to note is the metadata part - "Model1" obviously needs to be replaced for your model name.
Ref: http://msdn.microsoft.com/en-us/library/bb738533.aspx
EDIT 20/02/2013 22:25
So as an addition you'll need to extend the created DbContext class with a partial class that adds a constructor to support the above code, like this:
public partial class YourDbContext
{
public YourDbContext(string connection) : base(connection) {}
}
This class needs to be in the same namespace as the DbContext that is generated by the entity framework wizard.

Jetty Bind DataSource in JNDI Context

I would like to bind DataSource object to (eclipse) jetty's JNDI context programatically. I need for testing purpose. Here's a piece of code I have now:
server = new Server(SERVER_PORT);
webAppContext = new WebAppContext();
webAppContext.setResourceBase(".");
webAppContext.setContextPath("/" + SERVER_CONTEXT);
webAppContext.addEventListener(prepareServletContextListener());
webAppContext.addFilter(GuiceFilter.class, "/*", null);
webAppContext.addServlet(DefaultServlet.class, "/");
Resource r = new Resource(webAppContext,"jdbc/testDS",createDataSource());
server.setHandler(webAppContext);
server.start();
Of course the line with Resource isn't working.I have no idea how to bind it programatically to obtain sth similar to:
<New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
<Arg>
<New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
<Set name="Url">jdbc:mysql://localhost:3306/databasename</Set>
<Set name="User">user</Set>
<Set name="Password">pass</Set>
</New>
</Arg>
</New>
Any help would be greatly appreciated.
you need to add the defined resource object as attribute to the server object.
The following should work:
Resource r = new Resource("jdbc/testDS",createDataSource());
server.setAttribute("myDs", r);
I encountered the same issue and here is what I did to fix it:
server = new Server(PORT);
WebAppContext context = new WebAppContext();
context.setContextPath(CONTEXT);
context.setConfigurationClasses(new String[] { "org.eclipse.jetty.plus.webapp.PlusConfiguration",
"org.eclipse.jetty.webapp.FragmentConfiguration" });
// A filter needed by Guice, but this is independent
context.addFilter(GuiceFilter.class, "/*", 0);
PGSimpleDataSource simpleDataSource = new PGSimpleDataSource();
simpleDataSource.setDatabaseName("db-name");
simpleDataSource.setUser("user");
simpleDataSource.setPassword("pwd");
String jndiName = "jdbc/myDS";
Resource resource = new Resource("java:comp/env/" + jndiName, simpleDataSource);
server.setHandler(context);
// an event listener (because I use Guice, but this is independent)
GuiceServletConfig guiceServletConfig = new GuiceServletConfig();
context.addEventListener(guiceServletConfig);
server.start();
This requires to have the following additional libraries:
jetty-jndi
jetty-plus
I tested this code on Embedded Jetty 7 (7.6.10.v20130312)
The topic is old but I have encountered the same issue. Unfortunately existing answers provide no solution.
When you create a Resource specifying an instance of the DataSource, Jetty will not provide this instance when JNDI resource is requested. Instead constructor of Resource makes an attempt to transform the instance to some kind of "recipe" (javax.naming.Reference to be precise) that tells how to build the new instance of configuration with exact same internals.
It works well in case of basic classes but fails to recreate complex data structures (it failed with List<String> in my case). So you end up not getting:
the exact same instance (as you expect of a singleton)
the exact equivalent of the instance (as you expect of properly working JNDI)
I have implemented a wrapper that allows providing the instance specified when creating the Resource.
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
public class ExistingInstanceReference extends Reference implements ObjectFactory {
private Object instance;
private static final long serialVersionUID = -2718709718400909747L;
public ExistingInstanceReference() {
super(null);
}
public ExistingInstanceReference(Object instance) {
super(instance.getClass().getName(), ExistingInstanceReference.class.getName(), null);
this.instance = instance;
}
#Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
if (obj == null) {
return null;
}
ExistingInstanceReference reference = (ExistingInstanceReference) obj;
return reference.instance;
}
}
Note that this implementation fails to comply with Serializable interface as instance variable may contain non-serializable object.
Usage:
Resource r = new Resource(webAppContext, "jdbc/testDS", new ExistingInstanceReference(createDataSource()));
Please, consider this solution as a workaround because the real issue is still to be fixed somewhere in Jetty's sources. Unfortunately I have no time to trace this misbehavior to the root.
In addition, I had to set webAppContext.setParentLoaderPriority(true) because the webapp's classloader didn't see ExistingInstanceReference class in my setup.

JAXB How to force xsi:type in array of subclasses? (JBoss 4.2.3)

(Please note; i'm completely new to webservices, so the following may be stupid/incorrect but please be patient)
In my WebServices' #WebMethod I'm returning an array of an abstract base class (JAXB annotated entities in JBoss 4.2.3).
Obviously unless the type information is encoded per array element this will fail...
So how do I ensure that JAXB adds the xsi:type attribute?
My WebService interface has the following annotation, and I've tried every legal combination:
#SOAPBinding(style = RPC, parameterStyle = WRAPPED, use = LITERAL)
the methods on this interface take x2 parameters annotated #WebParam(name="...", mode=IN)
Other methods with similar signatures that don't return a heterogeneous array work perfectly.
Some related things:
Looks like JBoss uses the types defined in the method signatures to decide what classes to load into the JAXBContext - if I change the return types to Object[] it throws an error stating that the AbstractBase class "nor any of its super class is known to this context." I've added dummy methods returning the specific subclasses so that the generated WSDL has a list of all of them.
when I try to write tests for this, all is ok for single elements, but JAXB throws an error for array types: unable to marshal type "[LAbstractBase;" as an element because it is missing an #XmlRootElement annotation
From code like that shown below (note: AbstractBase, ConcreteOne and ConcreteTwo all have #XmlRootElement annotations)
private static final Class<?>[] CLASSES_TO_BE_BOUND = new Class<?>[]{
//Note; adding AbstractBase[].class doesn't work either
AbstractBase.class, ConcreteOne.class, ConcreteTwo.class
};
#Test
public void testXsiTypeAttributeIsIncludedInHeterogeneousArray()
{
AbstractBase[] array = new AbstractBase[2];
array[0] = new ConcreteOne();
array[1] = new ConcreteTwo();
Marshaller marshaller = createMarshaller();
StringWriter sw = new StringWriter();
marshaller.marshal(array, sw);
String output = sw.toString();
Assert.assertTrue(output.contains("xsi:type=\""));
}
private Marshaller createMarshaller() throws Exception {
JAXBContext context = JAXBContext.newInstance(CLASSES_TO_BE_BOUND);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
return marshaller;
}
Ideally I'd like to be able to test some bits relating to arrays, but it's far more critical that I can get the type information encoded per element in the JBoss environment.
Edit: Own Answer
JBoss (4.2.3) is doing something clever, but not too clever - it will handle the returning of arrays but not polymorphic arrays. This threw me a bit as I tried to get this way of doing it working in my tests.
Instead of trying to solve the JBoss WebService issue I made my tests more comprehensive - making the array a member of a simple container class and then annotating the array's getter with:
#XmlElementRefs({
#XmlElementRef(type = ConcreteOne.class),
#XmlElementRef(type = ConcreteTwo.class)
})
public AbstractBase[] getItems() { /*...*/ }
Which worked, and returning this in the JBoss WebService also worked! Though I'm using:
#SOAPBinding(style = DOCUMENT, parameterStyle = BARE, use = LITERAL)
So it's not adding the xsi:type attribute, but document nodes are correctly tagged:
<ConcreteOne>...</ConcreteOne>
At some point I'll change the WebService to use RPC as I don't really like the single argument restriction, but for now this is working fine.