i have created entity class from database then i have created session beans from entity class
and and when i am trying to test that my data reach the entity class i have created a junit test on the session beans class but i got lookup fail "Root exception is javax.naming.NameNotFoundException: EmpTableFacade!Beans.EmpTableFacade not found even if i used EJB injection
then i tried to test my code manually by creating class that use the session beans but the same exception here .
i think that the error from Deploying staff but i don't know where i did it wrong
this is session beans interface .
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Beans;
import java.util.List;
import javax.ejb.Local;
/**
*
* #author HADDAD
*/
#Local
public interface EmpTableFacadeLocal {
void create(EmpTable empTable);
void edit(EmpTable empTable);
void remove(EmpTable empTable);
EmpTable find(Object id);
List<EmpTable> findAll();
List<EmpTable> findRange(int[] range);
int count();
}
and this is the test class
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Controller;
import Beans.EmpTable;
import Beans.EmpTableFacade;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
*
* #author HADDAD
*/
public class Functionality {
List<EmpTable> l;
Context c=null;
{
try {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
// glassfish default port value will be 3700,
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
//props.load(new FileInputStream("jndi.properties"));
c = new InitialContext(props);
} catch (NamingException ex) {
Logger.getLogger(Functionality.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void retrive() throws NamingException
{
EmpTableFacade empTableFacade=(EmpTableFacade)
c.lookup("java:global/employee/employee-ejb/EmpTableFacade!Beans.EmpTableFacade");
l= empTableFacade.findAll();
System.out.println(l.get(0).getName().toString());
}
public static void main(String[] args) throws NamingException
{
Functionality f=new Functionality();
f.retrive();
}
}
and this is the exception
Exception in thread "main" javax.naming.NamingException: Lookup failed for 'java:global/employee/employee-ejb/EmpTableFacade!Beans.EmpTableFacade' in SerialContext[myEnv={org.omg.CORBA.ORBInitialPort=3700, java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory, org.omg.CORBA.ORBInitialHost=localhost, java.naming.factory.url.pkgs=com.sun.enterprise.naming, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [Root exception is javax.naming.NameNotFoundException: EmpTableFacade!Beans.EmpTableFacade not found]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at Controller.Functionality.retrive(Functionality.java:45)
at Controller.Functionality.main(Functionality.java:52)
You need to expose your bean with a Remote interface. A Local interface is available only for invocation within the same JVM, which it is not your case.
The JNDI name also looks wrong.
You donĀ“t specify which ejb or server version you are using which is important to solve this kind of problem, but I think this link can help you define the correct JNDI name entry.
Also take in mind that according to glassfish doc.
Each portable global JNDI name is printed out to the server.log during deployment.
Related
We have a Java program and a 3rd party API that stay in sync with Spring between the two.
After upgrading from 4.2.5.RELEASE to 5.0.7.RELEASE
I'm seeing the following error in one of the files:
The method parseStringValue(String, Properties, HashSet) is
undefined for the type
NestedPropertyPlaceholderConfigurer NestedPropertyPlaceholderConfigurer.java
I attempted to use this import instead PropertyPlaceholderHelper but then I seemed to be going down a rabbit hole of errors and I wasn't even sure that was the right approach.
This is the page of code in it's entirety (minus some redacted info):
package redacted.primavera.common.spring;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;
/**
* Extends the PropertyPlaceholderConfigurer to implement nested resource
* location placeholders. Properties from the top-level resources may be
* used to define nested resources.
*
* #author redacted
*
*/
public class NestedPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer implements ApplicationContextAware {
private ApplicationContext applicationContext;
private Resource[] topLocations;
private List<String> nestedLocations;
/*
* Post-process the bean factory. Add the nested resource locations to the
* top-level resource locations before processing.
*
* (non-Javadoc)
* #see org.springframework.beans.factory.config.PropertyResourceConfigurer#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
*/
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
Properties props = mergeProperties();
List<Resource> merged = new ArrayList<Resource>();
for (int i = 0; i < topLocations.length; i++) {
merged.add(topLocations[i]);
}
for (String nestedLocation : this.nestedLocations) {
String location = parseStringValue(nestedLocation.replaceAll("#\\{", "\\${"), props, new HashSet<String>());
if (location != null) {
Resource[] resources = this.applicationContext.getResources(location);
for (int i = 0; i < resources.length; i++) {
Resource resource = resources[i];
if (!merged.contains(resource)) {
merged.add(resource);
}
}
}
}
setLocations(merged.toArray(new Resource[merged.size()]));
}
catch (Exception e) {
throw new RuntimeException("", e);
}
super.postProcessBeanFactory(beanFactory);
}
/*
* (non-Javadoc)
* #see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/*
* Set resource locations and save a local copy.
*
* (non-Javadoc)
* #see org.springframework.core.io.support.PropertiesLoaderSupport#setLocations(org.springframework.core.io.Resource[])
*/
#Override
public void setLocations(Resource[] locations) {
this.topLocations = new Resource[locations.length];
System.arraycopy(locations, 0, this.topLocations, 0, locations.length);
super.setLocations(locations);
}
/**
* Set the nested resource locations.
* #param nestedLocations
*/
public void setNestedLocations(List<String> nestedLocations) {
this.nestedLocations = nestedLocations;
}
}
As you can see in the javadoc of version 4.x this method was deprecated and removed in version 5.x.
parseStringValue(String strVal, Properties props, Set visitedPlaceholders)
Deprecated.
as of Spring 3.0, in favor of using resolvePlaceholder(java.lang.String, java.util.Properties, int) with PropertyPlaceholderHelper. Only retained for compatibility with Spring 2.5 extensions.
So you have to refactor you code and use PropertyPlaceholderHelper
parseStringValue(String strVal, Properties props, Set visitedPlaceholders)
was deprecated.
As Jens suggested here is my refactored code changes to fix the compile issues:
Added an import:
import org.springframework.util.PropertyPlaceholderHelper;
Method variable:
PropertyPlaceholderHelper pph = new PropertyPlaceholderHelper(DEFAULT_PLACEHOLDER_PREFIX, DEFAULT_PLACEHOLDER_SUFFIX);
3. Replaced method call:
String location = pph.replacePlaceholders(nestedLocation.replaceAll("#\\{", "\\${"), props);
I know that there is a configuration file called web.xml
What I want to achieve is have another configuration file that has application specific configuration and it has to be read when the web server is started. I also want a Class to be able to read this configuration. Is there a way I can configure this is web.xml file itself or is there another way
You can use the Apache Commons Configuration. Have a look at the user guide. Since you want it to be done on startup here is a sample ServletContextListener:
package test;
import java.io.File;
import java.net.MalformedURLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
public class ConfigurationListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
File configFile;
try {
configFile = new File(context.getResource("/WEB-INF/configuration.xml").getPath());
Configuration config = new XMLConfiguration(configFile);
context.setAttribute("configuration", config);
} catch (ConfigurationException | MalformedURLException ex) {
Logger.getLogger(ConfigurationListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void contextDestroyed(ServletContextEvent sce) {}
}
Now get your configuration anywhere in your web application like this:
Configuration config = (Configuration) request.getServletContext().getAttribute("configuration");
I would create a class to hold the configuration though rather than adding it as an attribute to the ServletContext. The class would simply provide access to the configuration through a static method.
I am trying to write a simple stateless sesssion bean but I have problem with narrow reference I give in lookup time.
I got
class cast exeption
I use
eclipse IDE
my bean class
package codes;
import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class SinaBean implements SessionBean {
/**
*
*/
private static final long serialVersionUID = 1L;
public String getHello()
{
return "hello";
}
public void ejbCreate(){
}
#Override
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void ejbRemove() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void setSessionContext(SessionContext arg0) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
}
}
my home interface
package codes;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface SinaHome extends EJBHome {
public SinaObject create() throws RemoteException,CreateException;
}
my component
package codes;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface SinaObject extends EJBObject {
String getHello() throws RemoteException;
}
my client
package codes;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class Client {
/**
* #param args
*/
public static void main(String[] args) {
Context con=null;
try {
Properties p=new Properties();
p.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
p.setProperty(Context.PROVIDER_URL, "localhost:1099");
p.setProperty(Context.URL_PKG_PREFIXES,
"org.jboss.namingrg.jnp.interfaces");
con = new InitialContext(p);
Object o=con.lookup("SinaBean");
System.out.println(o);/***/untill know it works.it sysout :
//org.jnp.interfaces.NamingContext#e83912***
#SuppressWarnings("unused")
SinaHome sh=(SinaHome)PortableRemoteObject.narrow(o, SinaHome.class);//***exeption is here!!***
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
my xml file
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
<display-name>Ejb </display-name>
<enterprise-beans>
<session>
<display-name>SinaBean</display-name>
<ejb-name>SinaBean</ejb-name>
<home>codes.SinaHome</home>
<remote>codes.SinaObject</remote>
<ejb-class>codes.SinaBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<security-identity>
<description></description>
<use-caller-identity></use-caller-identity>
</security-identity>
</session>
</enterprise-beans>
</ejb-jar>
the exception I receive
java.lang.ClassCastException
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229)
at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137)
at codes.Client.main(Client.java:27)
Caused by: java.lang.ClassCastException: org.jnp.interfaces.NamingContext cannot be cast to org.omg.CORBA.Object
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212)
... 2 more
I will be extremely grateful for your advices.
First of all, your xml file indicates you are using EJB3 (which is actually the only version even worth considering), but your bean is an EJB2 bean.
If your server indeed runs EJB3, remove the XML file and remove the needless EJB home and component implementations. Add the #Stateless annotation and a remote interface. Make sure it looks something like this:
#Remote
public interface SinaRemote {
String getHello();
}
#Stateless
public class SinaBean implements SinaRemote {
public String getHello() {
return "hello";
}
}
Then correct your JNDI properties. The following is wrong:
p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.namingrg.jnp.interfaces");
it should be:
p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
(the variants people use here are almost endless and it basically always works anyway, but just to be sure use the correct variant)
Furthermore, and most likely the main culprit, you're using the ejb-name as-if it was a global JNDI name but this is not the case. The ejb-name is a somewhat confusing logical name that's used as an extra kind of qualifier when referring to a specific bean when injecting or creating an ejb-ref.
In your case you're setting it to the same as the unqualified bean name, which is already the default. Since SinaBean exists, I'm guessing you're not deploying via an EAR, but deploy a standalone EJB jar, right?
If you are using JBoss AS 6 (EJB3.1) you can use the global portable JNDI names, otherwise the old JBoss specific JNDI naming can be used: [ear name]/[simple bean name]/remote. Note that [simple bean name] is not the ejb-name, but again in your case they happened to be the same. Since [ear name]/ is removed when you're deploying only an EJB jar, this explains the exception you're getting: SinaBean is a directory (context in JNDI terms), which can contain the actual entries local, remote and no-interface. What you're doing is trying to cast this intermediate directory node to the proxy to your bean, which of course doesn't work.
Anyway, finally, remove the usage of PortableRemoteObject, this is no longer needed. The client code will then look like this:
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
properties.setProperty(Context.PROVIDER_URL, "localhost:1099");
context = new InitialContext(properties);
SinaRemote sina = (SinaRemote) context.lookup("SinaBean/remote");
Here If you are using EJB 2.0 along with Jboss 5.0 and trying to type cast Object obj to your Home Object from Client as below then it might throw java.lang.ClassCastException com.sun.proxy.$Proxy104 cannot be cast to org.omg.CORBA.Object .
Code to lookup JNDI :
java.lang.Object obj = ctx.lookup("java:comp/env/ATSessionBean");
ATHome home = (ATHome) PortableRemoteObject.narrow(obj, ATHome.class);
Solution : Here u need to add additional jars in classpath of Client app those are available in Higher version of JBOSS.
So better to download latest version **jboss-7.1.1.Final server and deploy your application and it will run successfully. :)**
download JBOSS server (Download EAP 6.4.0) from below link : http://jbossas.jboss.org/downloads/
I have a stateless session EJB as per 3.0 spec.
/*Remote Interface*/
package com.nseit.ncfm2.data.ejb;
import java.sql.SQLException;
import java.util.Collection;
import javax.ejb.Remote;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.naming.NamingException;
import com.nseit.ncfm2.security.Audit;
#Remote
public interface ProductionDataChangesRequestsRemote {
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public boolean shiftCandidateDetails(String sourceNcfmId,
String destinationNcfmId, Collection<String> specialCasesList, String shiftingRemarks, String user, Audit updtAudit) throws NamingException, SQLException;
}
/*Bean Class*/
package com.nseit.ncfm2.data.ejb;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.naming.NamingException;
import com.nseit.ncfm2.security.Audit;
import com.nseit.ncfm2.util.server.lookup.LookUpServerResources;
import java.sql.*;
import java.util.*;
/**
* Session Bean implementation class ProductionDataChangesRequestsBean
*/
#Stateless(name = "ProductionDataChangesRequestsBean", mappedName = "ProductionDataChangesRequestsEJB")
#Remote(ProductionDataChangesRequestsRemote.class)
#TransactionManagement(TransactionManagementType.CONTAINER)
public class ProductionDataChangesRequestsBean implements
ProductionDataChangesRequestsRemote {
/**
* Default constructor.
*/
public ProductionDataChangesRequestsBean() {
// TODO Auto-generated constructor stub
}
#Override
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public boolean shiftCandidateDetails(String sourceNcfmId,
String destinationNcfmId, Collection<String> specialCasesList,
String shiftingRemarks, String user, Audit updtAudit)
throws NamingException, SQLException {
// TODO Auto-generated method stub
Connection conn = null;
PreparedStatement pstmt = null;
int updtCnt = 0;
boolean areDetailsShifted = false;
try {
..............
..............
..............
/* Start: update table-1 */
..............
..............
..............
updtCnt = pstmt.executeUpdate();
..............
..............
..............
/* End: update table-1 */
/* Start: update table-2 */
..............
..............
..............
updtCnt = pstmt.executeUpdate();
..............
..............
..............
/* End: update table-2 */
areDetailsShifted = true;
} /*catch (SQLException e) {
// TODO Auto-generated catch block
System.out
.println("SQLException in ProductionDataChangesRequestsBean.shiftCandidateDetails(...) "
+ e.getMessage());
// e.printStackTrace();
context.setRollbackOnly();
} */finally {
LookUpServerResources.closeStatement(pstmt);
LookUpServerResources.closeConnection(conn);
}
return areDetailsShifted;
}
}
Currently, if the 1st table update succeeds and the 2nd table update gives an exception, a rollback is not taking place, i.e records in 1st table are updated.
I want the transaction to be rolled back in case an SQLException occurs (or for that matter, if any runtime exception occurs).
I tried two approaches :
Use of context.setRollbackOnly() in catch block for SQLException
Throwing the SQLException
In both the cases, the transaction didn't roll back.
How can I achieve this:
Without the usage of #ApplicationException annotation (as I do not have any application exceptions)
Without catching the SQLException and then calling context.setRollbackOnly()
Or what is the standard way?
You will have to throw RuntimeException
The standard way is to use underlying JPA for persistence rather then using JDBC.
JPA provides a standard OR mapping solution that's well-integrated into an EJB 3.x-compliant container.
Also from your code it reflects that you have TransactionManagementType.CONTAINER , but still managing transaction manually.
In bean-managed transaction
demarcation, the code in the session
or message-driven bean explicitly
marks the boundaries of the
transaction. Although beans with
container-managed transactions require
less coding, they have one limitation:
When a method is executing, it can be
associated with either a single
transaction or no transaction at all.
If this limitation will make coding
your bean difficult, you should
consider using bean-managed
transactions.
It looks like you are using JDBC API in your bean. I don't think container manages those JDBC transactions. For CMT, you'd have to invoke operations on a container managed entity manager for the rollback to work as expected.
I am trying to develop a Basic EJB3 application on JBOSS 4.2 in Eclipse
I have created an EJB project in eclipse.
The following are my remote and local interfaces.
package com.test;
import javax.ejb.Local;
#Local
public interface HelloWorldLocal
{
public String getGreeting();
}
package com.test;
import javax.ejb.Remote;
#Remote
public interface HelloWorldRemote
{
public String getGreeting();
}
and my ejb implementation is
package com.test;
import javax.ejb.Stateless;
#Stateless
public class HelloWorld implements HelloWorldRemote, HelloWorldLocal {
public HelloWorld() {
// TODO Auto-generated constructor stub
}
public String getGreeting() {
// TODO Auto-generated method stub
return "First EJB People";
}
}
I have deployed this as an exploded JAR in JBoss and it runs fine.
My first question is:
What else do I have to add to this exploded jar ?
Secondly I created a stand alone client and added the above jar to its classpath
The client code is as follows
package com.testejb;
import java.io.FileInputStream;
import java.util.Properties;
import javax.naming.InitialContext;
public class TestBean {
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
HelloWorldRemote getMess = null;
try {
Properties props = new Properties();
Properties props = new Properties();
props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
props.setProperty("java.naming.provider.url", "localhost:1099");
InitialContext ic = new InitialContext(props);
//
getMess = (HelloWorldRemote) ic.lookup("HelloWorldRemote/remote");
System.out.println(getMess.getGreeting());
} catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
}
The name of the jar is FirstEJB.
I have tried the look up as FirstEJB/HelloWorldRemote/remote.
But when I run the program I get the error
javax.naming.NameNotFoundException: HelloWorldRemote not bound
If I type the lookup as HelloWorld/remote i get the error
Caused by: java.io.InvalidClassException: org.jboss.ejb3.remoting.BaseRemoteProxy; local class incompatible: stream classdesc serialVersionUID = 1126421850898582900, local class serialVersionUID = -2711693270411201590
What else do I have to add to this exploded jar ?
Nothing, it's usable.
I have tried the look up as FirstEJB/HelloWorldRemote/remote
With JBoss, the JNDI name will be:
<myEarName>/<EJB-Name>/remote
Where the EJB-Name defaults to the Bean name if not specified. So in your case, without using an EAR packaging, the JNDI name should be:
HelloWorld/remote
This should be logged in the server logs at deployment time by the way.
If I type the lookup as HelloWorld/remote I get the error (...)
The JNDI name used for the lookup is correct, this error is another problem that looks very similar to EJBTHREE-1118. Could you try with JBoss 4.2.3.GA?