CORBA.UNKNOWN Exception on method call
Hi all,
for learning purposes, I created an EJB 'Pricing'.
I have written all classes and interfaces and it seems to be all as it should be. I have it compiled and deployed.
I get the HomeInterface, I get the session but as soon as I try to call any method of the EJB I get a CORBA.UNKNOWN Exception.
Does anybody have an idea of what could be the reason? Or how I can get Details about the Exception?
Server does not react - no output in logfile...
Pls help,
thanks in advance
Anke
Hi Anke,Can you post the code please..Cheers
Hi,
here comes the code...
// HomeIF
public interface PricingHome extends EJBHome {
// defines method for creating pricing-bean
public Pricing create() throws RemoteException, CreateException;
}
//RemoteIF
public interface Pricing extends EJBObject
{
/** Returns all the available product codes */
public String[] getProductCodes() throws RemoteException;
}
//Bean itself
public class PricingImpl implements SessionBean{
/** The session context */
private SessionContext context;
/** The database connection*/
private Connection conn;
/** constructor */
public PricingImpl() {
}
/** Called by the EJB container to set this session's context */
public void setSessionContext(SessionContext aContext) {
context = aContext;
}
/** Called by the EJB container when a client calls the create() method in
the home interface */
public void ejbCreate() throws CreateException {
try {
// Allocate a database connection
conn = getConnection();
}
catch (Exception exc) {
throw new CreateException("Unable to access database: "+exc.toString());
}
}
/** Called by the EJB container for putting bean to sleep). */
public void ejbPassivate() throws EJBException {
try {
// Shut down the current database connection
conn.close();
conn = null;
}
catch (Exception exc) {
throw new EJBException("Unable to close database connection: "+
exc.toString());
}
}
/** Called by the EJB container to wake this session bean up */
public void ejbActivate() throws EJBException {
try {
// When the bean wakes back, connect DB again
conn = getConnection();
}
catch (Exception exc) {
throw new EJBException("Unable to access database: "+exc.toString());
}
}
/** Called by the EJB container to tell this session bean that it has been
removed*/
public void ejbRemove() throws EJBException {
try {
// Shut down the current database connection
conn.close();
conn = null;
}
catch (Exception exc) {
throw new EJBException("Unable to close database connection: "+
exc.toString());
}
}
/** Returns a list of the available product codes */
public String[] getProductCodes() throws EJBException {
Statement s = null;
try {
s = conn.createStatement();
ResultSet results = s.executeQuery(
"select product_code from price");
Vector v = new Vector();
// Copy the results into a temporary vector
while (results.next()){
v.addElement(results.getString("product_code"));
}
// Copy the vector into a string array
String[] productCodes;
v.copyInto(productCodes);
return productCodes;
}
catch (Exception e){
throw new EJBException("Unable to get product codes: "+
e.toString());
}
finally {
// Close down the statement in a finally block to guarantee that it gets
// closed, whether an exception occurred or not
try{
s.close();
}
catch (Exception ignore) {
}
}
}
protected Connection getConnection()
throws SQLException, NamingException {
// Get a reference to the naming service
InitialContext context = new InitialContext();
// Get the data source for the pricing database
DataSource ds = (DataSource) context.lookup(
"java:comp/env/jdbc/testDB");
// Ask the data source to allocate a database connection
return ds.getConnection();
}
}
//Client
public class TestPricing
{
public static void main(String[] args)
{
try
{
/** Creates a JNDI naming context for location objects */
Context context = new InitialContext();
/** Asks the context to locate an object named "Pricing" and expects the
object to implement the PricingHome interface */
PricingHome home = (PricingHome)
PortableRemoteObject.narrow(context.lookup("Pricing"),
PricingHome.class);
/** Asks the Home interface to create a new session bean */
Pricing session = (Pricing) home.create();
/** Get a list of valid product codes */
String[] codes = session.getProductCodes();
for (int i=0; i < codes.length; i++)
{
System.out.println(codes+": "+
session.getPrice(codes));
}
/** Destroy this session */
session.remove();
}
catch (Exception exc)
{
exc.printStackTrace();
}
}
}
Thanks for having a look at it,
regards
Anke
Hi,
missed something...
of course initialisation of string must be like this:
// Copy the vector into a string array
String[] productCodes = new String[v.size()];
v.copyInto(productCodes);
Just had tried something before and kept it in the code....
Still does not work. :-(
Anke
Hi Anke
When setting up an InitialContext from a client you need to provide it with some information, not just use the no arg constructor. It tends to be app server dependent so you'll have to experiment / look for examples. But will be of the form:
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY,"name of app servers's factory class");
prop.put(Context.PROVIDER_URL,"localhost:7001");
Context ctx = new InitialContext(prop);
Good luck.
Hello,
thank you.
I tried your suggestion, but it did not work. I took the InitialContextFactory that is used in the jndi.properties - file.
I had another bean before, using as well the Context Constructor for the initial context without arguments and it worked all right.
It's really strange - I think if it was the context it would'nt even find the bean - isn't it?
But it gets an instance of the bean - the bean is created, what fails are the method calls.
I'm really desperate now - I hate those days!!!
Anybody an idea?
Anke
I guess if you don't have a remote client, it might work (well it obviously does if you get to the method calls). What app server are you running?
Hi,
Are you using J2EE reference implementation?. If yes, shouldn't you be looking up your EJB as something like
PricingHome home = (PricingHome) PortableRemoteObject.narrow (context.lookup("java:comp/env/ejb/Pricing"), PricingHome.class);
would be interested what your DD (ejb-jar.xml) looks like?
Hi again,
I'm using the J2EE server, which is included in the j2sdkee installation from sun. But I think I will try the same with BEA weblogic, maybe it works better...
The narrow() uses the JNDI-name. I deployed my bean as 'Pricing'. I did the same before with the other beans and it worked.
I'm using the book J2EE Developer's Guide by Mark Wutka.
I don't have an ejb-jar.xml... hmmmmm - should I?
There is an application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN' 'http://java.sun.com/dtd/application_1_3.dtd'>
<application>
<display-name>HelloWorld</display-name>
<description>Application description</description>
<module>
<ejb>ejb-jar-ic.jar</ejb>
</module>
<module>
<ejb>ejb-jar-ic3.jar</ejb>
</module>
</application>
and a sun-j2ee-ri.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE j2ee-ri-specific-information PUBLIC '-//Sun Microsystems Inc.//DTD J2EE Reference Implementation 1.3//EN' 'http://localhost:8000/sun-j2ee-ri_1_3.dtd'>
<j2ee-ri-specific-information>
<server-name></server-name>
<rolemapping />
<enterprise-beans>
<module-name>ejb-jar-ic.jar</module-name>
<unique-id>0</unique-id>
<ejb>
<ejb-name>Pricing</ejb-name>
<jndi-name>Pricing</jndi-name>
<ior-security-config>
<transport-config>
<integrity>supported</integrity>
<confidentiality>supported</confidentiality>
<establish-trust-in-target>supported</establish-trust-in-target>
<establish-trust-in-client>supported</establish-trust-in-client>
</transport-config>
<as-context>
<auth-method>username_password</auth-method>
<realm>default</realm>
<required>false</required>
</as-context>
<sas-context>
<caller-propagation>supported</caller-propagation>
</sas-context>
</ior-security-config>
<resource-ref>
<res-ref-name>jdbc/testDB</res-ref-name>
<jndi-name>jdbc/Cloudscape</jndi-name>
</resource-ref>
<gen-classes />
</ejb>
</enterprise-beans>
<enterprise-beans>
<module-name>ejb-jar-ic3.jar</module-name>
<unique-id>0</unique-id>
<ejb>
<ejb-name>StatelessHello</ejb-name>
<jndi-name>StatelessHello</jndi-name>
<ior-security-config>
<transport-config>
<integrity>supported</integrity>
<confidentiality>supported</confidentiality>
<establish-trust-in-target>supported</establish-trust-in-target>
<establish-trust-in-client>supported</establish-trust-in-client>
</transport-config>
<as-context>
<auth-method>username_password</auth-method>
<realm>default</realm>
<required>false</required>
</as-context>
<sas-context>
<caller-propagation>supported</caller-propagation>
</sas-context>
</ior-security-config>
<gen-classes />
</ejb>
</enterprise-beans>
</j2ee-ri-specific-information>
Hi,
You definitely need an ejb-jar.xml !!.. This tells you what your ejb classes and assembly descriptors are.. A simple way to start off is to use the 'deploytool' to package your bean classes into an JAR file which containes your bean implementation, home and remote and your ejb-jar.xml.
Deploy this to your j2ee RI server and then run the client test. Make sure to select ' Return client jar' option when you deploy because you need them to make your client access the remote objects.
Follow the j2ee tutorial for a walk thro'
http://java.sun.com/j2ee/sdk_1.2.1/techdocs/guides/ejb/html/DevGuideTOC.html
Cheers
I finally found the ejb-jar.xml.
I just looked for it in the wrong .jar-file.
I'm already using the deploytool and it works fine for the other programs. But this one really drives me crazy.
I started playing with the deploytool. I changed the settings for the bean, it's now a stateful bean (though in the example it should be stateless).
Now I get
SQL Exception. Connection refused to host: XXX
when trying to initialise the DB connection.
CU and thanks a lot
Anke
OK, I could have posted the ejb-jar.xml. Here is it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
<display-name>Pricing</display-name>
<enterprise-beans>
<session>
<display-name>Pricing</display-name>
<ejb-name>Pricing</ejb-name>
<home>wutka.pricing.PricingHome</home>
<remote>wutka.pricing.Pricing</remote>
<ejb-class>wutka.pricing.PricingImpl</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Bean</transaction-type>
<security-identity>
<description></description>
<use-caller-identity></use-caller-identity>
</security-identity>
<resource-ref>
<res-ref-name>jdbc/testDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</session>
</enterprise-beans>
<assembly-descriptor>
<method-permission>
<unchecked />
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Home</method-intf>
<method-name>remove</method-name>
<method-params>
<method-param>java.lang.Object</method-param>
</method-params>
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getPrice</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getProductCodes</method-name>
<method-params />
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getHandle</method-name>
<method-params />
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Home</method-intf>
<method-name>remove</method-name>
<method-params>
<method-param>javax.ejb.Handle</method-param>
</method-params>
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Home</method-intf>
<method-name>getHomeHandle</method-name>
<method-params />
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getPrimaryKey</method-name>
<method-params />
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Remote</method-intf>
<method-name>remove</method-name>
<method-params />
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Home</method-intf>
<method-name>getEJBMetaData</method-name>
<method-params />
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Home</method-intf>
<method-name>create</method-name>
<method-params />
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Remote</method-intf>
<method-name>isIdentical</method-name>
<method-params>
<method-param>javax.ejb.EJBObject</method-param>
</method-params>
</method>
<method>
<ejb-name>Pricing</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getEJBHome</method-name>
<method-params />
</method>
</method-permission>
</assembly-descriptor>
</ejb-jar>
I get the ejb-jar.xml only if the J2EE server is running, and the bean is succesfully created. If I have the SQL exception, the bean is not created (CreateException due to SQLException).
Cheers
Anke
