EJB remote invoke lookup Weblogic - Liferay - java

I'm new with EJB and Im trying to consume a remote EJB from Liferay. EJB is deployed on WebLogic, Im using t3 client (wlthint3client.jar).
Part of the code of EJB is:
Stateless(name = "myDataEJB", mappedName = "ejb/MyDataEJB",
description = "Get important Data")
#Remote({
MyDataEJB.class,
SecurityContext.class
})
#RolesAllowed({
"MyRole"
})
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyDataEJBEJBImpl extends TheBaseSpringSecurityEJB implements MyDataEJBEJB {
//some stuff
And my code from Liferay is the next:
Properties p = new Properties();
p.put(Context.PROVIDER_URL, "t3://someip:someip,anotherip:anotherport");
p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
p.put(Context.SECURITY_PRINCIPAL, "some");
p.put(Context.SECURITY_CREDENTIALS, "somepass");
try {
Context ctx = new InitialContext(p);
MyDataEJB mydataEJB =
(MyDataEJB)ctx.lookup("ejb/MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB");
And I´m getting this:
javax.naming.NameNotFoundException: While trying to lookup 'ejb.MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB' didn't find subcontext 'MyDataEJB#com'. Resolved 'ejb'[Root exception is javax.naming.NameNotFoundException:While trying to lookup 'ejb.MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB' didn't find subcontext 'ejb.MyDataEJB#com.Resolved 'ejb'] remaining name 'ejb.MyDataEJB#com/company/proyect/worker/ejb/MyDataEJB''
Do you have any idea about what's happening?
Is the pattern ejb/MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB for my lookup wrong?
Thank you so much! :)

try to use
MyDataEJB mydataEJB =
(MyDataEJB)ctx.lookup("ejb/MyDataEJB");
because your EJB is mapped by ejb/MyDataEJB in the JNDI.

Related

Code in Persistent EHcache docs not working java

I want to use EHcache in my java project. They have persistent storage support. I have read the docs
https://www.ehcache.org/documentation/2.7/configuration/fast-restart.html and found this code
Configuration cacheManagerConfig = new Configuration()
.diskStore(new DiskStoreConfiguration()
.path("/tmp/file.txt"));
CacheConfiguration cacheConfig = new CacheConfiguration()
.name("my-cache")
.maxBytesLocalHeap(16, MemoryUnit.MEGABYTES)
.maxBytesLocalOffHeap(256, MemoryUnit.MEGABYTES)
.persistence(new PersistenceConfiguration().strategy(Strategy.LOCALTEMPSWAP));
cacheManagerConfig.addCache(cacheConfig);
CacheManager cacheManager = new CacheManager(cacheManagerConfig);
Ehcache myCache = cacheManager.getEhcache("my-cache");
I have imported the dependency but it shows lots of error.
Error I got
'Configuration' is abstract; cannot be instantiated
Please provide some simple steps to make use of this library. I read the docs but the code doesn't get worked. Help me with some solutions.
Found the Answer.
try(PersistentCacheManager persistentCacheManager =
newCacheManagerBuilder()
.with(persistence("/tmp/myProjectCache"))
.withCache("test-cache",
newCacheConfigurationBuilder(
String.class, String.class,
newResourcePoolsBuilder()
.heap(1, EntryUnit.ENTRIES)
.offheap(1, MemoryUnit.MB)
.disk(2, MemoryUnit.MB, true)
)
).build(true)) {
org.ehcache.Cache cache = persistentCacheManager.getCache("test-cache", String.class, String.class);
cache.put("name1","steven");
cache.put("name2","prince");
System.out.println(cache.get("name1"));
System.out.println(cache.get("name2"));
}

Grails: how to call a service and the service name from a string

I want to call services dynamically so the service name will get as a string value, we can list all the services names in the grails project by using the code below.
import org.codehaus.groovy.grails.plugins.metadata.GrailsPlugin
for (type in ['service']) {
for (artifactClass in ctx.grailsApplication."${type}Classes") {
def clazz = artifactClass.clazz
def annotation = clazz.getAnnotation(GrailsPlugin)
if (annotation) {
println "$type $clazz.name from plugin '${annotation.name()}'"
}
else {
println "$type $clazz.name from application"
}
}
}
Here we will get artifactClass of the service.Is there any option to call the service by using this idea.Please help me.
You can get the bean for the service from the applicationContext
//inject application context bean
def applicationContext
//to use
applicationContext."${yourServiceName}".serviceMethod()
You can get the bean of your service this way:
import grails.util.Holders
...
YourService yourService =
(YourService)Holders.grailsApplication.mainContext["yourService"]

Reference EJBs outside the Application server

I would like to know if any of you have ever call an EJB remotely. This is my scenario:
I have a single remote interface package in its own jar file. Then there is a EJB module (another jar file) that depends on the previous one to implement the interface as a #Stateless session bean.
I have deployed the EJB module in JBOSS 5.1.0.GA. When I try calling the EJB from within Eclipse, the returned object is not recognized as being of the interface type. Below are the differents java codes.
The Business interface:
#Remote
public interface RemoteBusinessInterface
{
public CustomerResponse getCustomerData( final CustomerRequest customerRequest );
}
Implementing class package in its own jar file:
#Stateless
public class RemoteEJBBean implements RemoteBusinessInterface
{
public CustomerResponse getCustomerData( final CustomerRequest customerRequest )
{...
And The code calling the remote EJB:
public class TestRemoteEjb
{
public static void main( final String[] args )
{
try
{
InitialContext initialContext = new InitialContext();
Object ref = initialContext.lookup( "java:/CustomerServiceBean/remote" );
System.out.println( ref );
if ( ref instanceof RemoteBusinessInterface )
{
System.out.println( "RemoteBusinessInterface" );
}
else
{
System.out.println( "Not of type RemoteBusinessInterface" );
}
}
catch ( NamingException e )
{
e.printStackTrace();
}
}
}
The output reads:
Reference Class Name: Proxy for: com.tchouaffe.remote.interfaces.RemoteBusinessInterface
Type: ProxyFactoryKey
Content: ProxyFactory/remote-ejb-1.0.0-SNAPSHOT/CustomerServiceBean/CustomerServiceBean/remote
Type: EJB Container Name
Content: jboss.j2ee:jar=remote-ejb-1.0.0-SNAPSHOT.jar,name=CustomerServiceBean,service=EJB3
Type: Proxy Factory is Local
Content: false
Type: Remote Business Interface
Content: com.tchouaffe.remote.interfaces.RemoteBusinessInterface
Type: Remoting Host URL
Content: socket://127.0.0.1:3873/
Not of type RemoteBusinessInterface
I have been wondering why the returned object is of a type other than RemoteBusinessInterface.
Thanks for any help.
Edmond
Try to check the following point:
It seems to be that you are not initializing the InitialContext object.
According to JBoss 5 documentation the properties needed are:
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.NamingContextFactory");
env.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
env.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
InitialContext context = new InitialContext(env);
Additionaly, try to check if your client code has the necessary dependencies. The documentation is not clear enough about what are the jar files, but this link can help you to identify them. You also need to include the jar with the remote interface.

Websphere Network deployment datasource

I have installed Websphere Network deployment server 7.0.0.0
I have configured a cluster on it.
I have configured a data source on it say ORA_DS this data source using "JAAS - J2C authentication data"
When i test the ORA_DS by clicking on "Test connection" button, the test connection is success.
The issue comes when i try to access this data source using my java code.
Here is my code to access data source and create a connection:
public class DSTester
{
/**
* Return the data source.
* #return the data source
*/
private DataSource getDataSource()
{
DataSource dataSource = null;
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL, "iiop://localhost:9811");
// Retrieve datasource name
String dataSourceName = "EPLA1";
if (dataSource == null)
{
try
{
Context initialContext = new InitialContext(env);
dataSource = (DataSource) initialContext.lookup(dataSourceName);
}
catch (NamingException e1)
{
e1.printStackTrace();
return null;
}
}
return dataSource;
}
public static void main(String[] args)
throws Exception
{
DSTester dsTester = new DSTester();
DataSource ds = dsTester.getDataSource();
System.out.println(ds);
System.out.println(ds.getConnection());
}
}
Here is the output:
com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource#17e40be6
Exception in thread "P=792041:O=0:CT" java.sql.SQLException: ORA-01017: invalid username/password; logon denied
DSRA0010E: SQL State = 72000, Error Code = 1,017
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:406)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4CTTIoauthenticate.receiveOauth(T4CTTIoauthenticate.java:799)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:368)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:508)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:203)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:510)
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:275)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:206)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPhysicalConnection(OracleConnectionPoolDataSource.java:139)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:88)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:70)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:1175)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:1212)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:2019)
at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1422)
at com.ibm.ws.rsadapter.spi.WSDefaultConnectionManagerImpl.allocateConnection(WSDefaultConnectionManagerImpl.java:81)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:646)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:613)
at com.test.DSTester.main(DSTester.java:70)
The code works fine if i replace
ds.getConnection()
with
ds.getConnection("ora_user", "ora_password")
My issue is i need to get the connection without specifying login details for Oracle.
Please help me on this issue.
Any clue will be appreciated.
Thanks
I'd guess it would work if you retrieved the datasource from an application running on the WAS.
Try creating a servlet.
Context initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup("EPLA1");
Connection con = dataSource.getConnection();
As within a servlet it is running within WAS it should be fine, if the "Test Connection" works. Running it outside is probably a different context.
I think you need to check all your configuration:
1) Is it application deplyed on cluster or into only one of cluster member?
2) JAAS - J2C authentication data - what is the scope?
Sometimes you need restar all your WAS environment. It depends on resource configuration scope
I'd recomend to you add resource refences for better configuration options.
SeeIBM Tech note

Can an EJB be called from a desktop application?

I am new in Java EJB 3.0. It is possible to call a (session) bean—deployed on JBoss—from a desktop application client?
Thanks in advance.
Yes you can. Some specifics are here (references EJB2 but it the same for EJB3 when it comes to remote clients): http://www.theserverside.com/discussions/thread.tss?thread_id=9197
Paraphrased:
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
env.put("java.naming.provider.url", "jnp://localhost:1099");
env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
Context ctx = new InitialContext(env);
// name is whatever JNDI name you gave it
Object o = ctx.lookup("home name");
EJBHome ejbHome = (EJBHome) PortableRemoteObject.narrow(o,EJBHome.class);
// This is userID should be the one passed.
EJB ejb = ejbHome.create(..);
Yes.
public static void main(String args[]) throws Exception {
InitialContext ctx = new InitialContext();
YourService yourService = (YourService) ctx.lookup("com.example.session.YourService");
String time = yourService.getTime();
System.out.println("Time is: " + time);
}
For client configuration you must provide jndi.properties file with contents
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
If you are looking for working examples on JBoss try download source code of Enterprise JavaBeans 3.0, Fifth Edition
Let's assume you have the following remote interface:
#Remote
public interface HelloBeanRemote {
public String sayHello();
}
And a session bean implementing it:
#Stateless
public class HelloBean implements HelloBeanRemote {
...
}
And that this EJB is correctly packaged and deployed on JBoss.
On the client side, create a jndi.properties with the following content and put it on the classpath:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost:1099
Then use the following code to call your EJB:
Context context;
try {
context = new InitialContext();
HelloBeanRemote beanRemote = (HelloBeanRemote)context.lookup("HelloBean/remote");
beanRemote.test();
} catch (NamingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
Alternatively, if you don't want to provide a jndi.properties file, you can explicitly setup the JNDI environment in the code and create the context like this:
Properties properties = new Properties();
properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs","=org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url","localhost:1099");
Context context = new InitialContext(properties);
But I'd recommend using the jndi.properties for the sake of portability.
You can also expose the bean as a web service. I believe this is available as of EJB 3. It is quite nice considering you can do it with annotations. You may wish to consider using this option to decrease coupling. Here is a link to a tutorial.

Categories

Resources