after quite a while I made the remote access to a stateless EJB run under JBoss 7.1.1. using Properties object:
Properties jndiProps = new Properties();
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put(Context.PROVIDER_URL,"remote://localhost:4447");
jndiProps.put(Context.SECURITY_PRINCIPAL, "remote");
jndiProps.put(Context.SECURITY_CREDENTIALS, "remotepwd");
jndiProps.put("jboss.naming.client.ejb.context", true);
Context ctx = new InitialContext(jndiProps);
String lookupString = "//HelloWorld/HelloWorldBean!org.acme.test.HelloWorld";
HelloWorld hw = (HelloWorld) ctx.lookup(lookupString);
System.out.println("Response: "+ hw.sayHello("Hi there"));
So this works fine but now I want to put the JNDI thing into jndi.properties file but failed, this is how the file looks like:
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
java.naming.provider.url=remote://localhost:4447
java.naming.security.principal=remote
java.naming.security.credentials=remotepwd
The exception:
Exception in thread "main" java.lang.IllegalStateException: No EJB receiver available for handling [appName:,modulename:HelloWorld,distinctname:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#108c175
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119)
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104)
at $Proxy0.sayHello(Unknown Source)
at de.brockhaus.test.client.TestClient.main(TestClient.java:35)
I already went through several doco but failed, so how does it have to look like then?
OK, so I found the answer myself ...
First you need to have two properties files, jndi.properties plus jboss-ejb-client.properties.
jndi.properties:
#
# jndi.properties
#
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
java.naming.provider.url=remote://localhost:4447
java.naming.security.principal=remote
java.naming.security.credentials=remotepwd
jboss-ejb-client.properties:
#
# jboss-ejb-client.properties
#
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
Having both of them on the classpath will make the code run like a charm even without specifying the properties within the code.
Still confusing is the construction of the lookup string ...
Related
I'm trying to do Remote EJB calls to my Wildfly 10/JBoss 7 EAP server, but keep getting Invalid User error messages on my Wildfly server (my EJB is called LoginManager):
23:04:02,872 ERROR [org.jboss.as.ejb3.invocation] (default task-6) WFLYEJB0034: EJB Invocation failed on component LoginManager for method public abstract java.lang.String ejbs.LoginManagerRemote.echo(java.lang.String): javax.ejb.EJBAccessException: WFLYSEC0027: Invalid User
at org.jboss.as.ejb3.security.SecurityContextInterceptor$1.run(SecurityContextInterceptor.java:69)
at org.jboss.as.ejb3.security.SecurityContextInterceptor$1.run(SecurityContextInterceptor.java:49)
at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:97)
I've added my user to the application-users.properties file using the add-user.sh/bat scripts.
I've tried putting in breakpoints in the Wildfly server itself in the SecurityContextInterceptor class on line 54 and see that the principal is null:
if (holder.skipAuthentication == false) {
holder.securityManager.authenticate(holder.runAs, holder.runAsPrincipal, holder.extraRoles);
I'm not entirely sure if this runAs or runAsPrincipal is the principal/credentials passed by the remote EJB invocation, but I suspect it might be responsible for my problem.
I'm calling the remote ejb as:
Properties p = new Properties();
p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(p);
LoginManagerRemote ejb = (LoginManagerRemote) context.lookup("ejb:ear-1.0/ejbs-1.0//LoginManager!ejbs.LoginManagerRemote");
return ejb.echo("test");
with my jboss-ejb-client.properties as:
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.conncetion.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER
remote.connection.default.username=test
remote.connection.default.password=test
Am I doing something wrong? Am I missing something obvious somewhere? What do I need to do to successfully call a remote EJB?
There's a typo in your jboss-ejb-client.properties
remote.conncetion.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER
Should be remote.connection.default.connect.options etc etc
I'm trying to run an application using a Datasource on JBOSS EAP 6.4
In the standalone.xml file my data source is well defined.
When I try a :
Context context = new InitialContext();
NamingEnumeration<NameClassPair> list = context.list("");
while (list.hasMore())
{
String name = list.next().getName();
System.out.println(name);
}
I only get TransactionManager while I'm expecting as well my data source named in the standalone.xml as jndi-name="java:jboss/datasources/OracleDS".
Why my datasource is not defined in the jndi environnement? Am I missing some configuration?
The Context.list(Name) does not include subcontexts. In other words you cannot iterate through all the registered names using context.list(""). If you want to list the data sources you'd need to use context.list("java:jboss/datasources).
The reason you only get the /TransactionManager is because it's the only one defined under the root namespace.
I already have a integration-test phase, when I ran the selenium tests. I also want to run some unit tests in this phase, because the app is too much complex and have a lot of dependencies between his modules (a hell), so, after a week fighting against OpenEJB and Arquillian, I believe that this would be easier.
The thing is: how do I made it work?
I have the instance already running, if I instantiate an InitialContext and try to lookup some bean, I got an exception telling me that I have not set the java.naming.initial.factory, and I don't know what to put in there.
I'm also complaining about the annotated beans.
Suppose a Bean like this:
#Stateless
public class ABeanImpl implements ABean {
#EJB
private BBean;
}
Will the container automatically get right the BBean?
Thanks in advance
How to connect to JBoss 7.1 remote JNDI:
Here is the code snippet that I use for JBoss 7.1:
Properties props = new Properties();
String JBOSS_CONTEXT = "org.jboss.naming.remote.client.InitialContextFactory";
props.put("jboss.naming.client.ejb.context", true);
props.put(Context.INITIAL_CONTEXT_FACTORY, JBOSS_CONTEXT);
props.put(Context.PROVIDER_URL, "remote://localhost:4447");
props.put(Context.SECURITY_PRINCIPAL, "jboss");
props.put(Context.SECURITY_CREDENTIALS, "jboss123");
InitialContext ctx = new InitialContext(props);
Resolution of ambiguous ejb references:
According to JBoss EJB 3 reference, if at any level of your EJB environment (EJB/EAR/Server) are duplicates in used interfaces, exception will be thrown during resolution of injected beans.
Based on above, if you have got a reference to EJB bean which interface:
has two implementations in your EJB module (JAR/WAR) - exception will be thrown
has two implementations in your application (other EJB JAR's in same EAR) - exception will be thrown
has two implementations, one in module with bean ABeanImpl, second somewhere else - implemetation from current module is used.
I'm trying to use Apache Shiro (v1.2) in a JavaEE6 web application on a GlassFish v3.1.2 application server.
In GlassFish I've set up a datasource (jdbc/myds) which I have tested to work through JPA2.
I would like to use the same datasource for authenticating users using the Shiro JDBC realm.
I've got the following in shiro.ini:
# DataSource config
ds = org.apache.shiro.jndi.JndiObjectFactory
ds.requiredType = javax.sql.DataSource
ds.resourceName = jdbc/myds
# JDBC realm config
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = false
jdbcRealm.authenticationQuery = SELECT password FROM user_account WHERE email = ?
jdbcRealm.userRolesQuery = SELECT role_name FROM user_group_membership WHERE email = ?
jdbcRealm.dataSource = $ds
When I deploy the application I get the following Exception (summarised):
FINE: Encountered object reference '$ds'. Looking up object with id 'ds'
FINEST: Applying property [dataSource] value [org.apache.shiro.jndi.JndiObjectFactory#2ca061] on object of type [org.apache.shiro.realm.jdbc.JdbcRealm]
SEVERE: Unable to start Filter: [Unable to set property 'dataSource' with value [$ds] on object of type org.apache.shiro.realm.jdbc.JdbcRealm. If '$ds' is a reference to another (previously defined) object, prefix it with '$' to indicate that the referenced object should be used as the actual value. For example, $$ds].
org.apache.shiro.config.ConfigurationException: Unable to set property 'dataSource' with value [$ds] on object of type org.apache.shiro.realm.jdbc.JdbcRealm. If '$ds' is a reference to another (previously defined) object, prefix it with '$' to indicate that the referenced object should be used as the actual value. For example, $$ds
at org.apache.shiro.config.ReflectionBuilder.applyProperty(ReflectionBuilder.java:373)
at org.apache.shiro.config.ReflectionBuilder.applySingleProperty(ReflectionBuilder.java:198)
at org.apache.shiro.config.ReflectionBuilder.applyProperty(ReflectionBuilder.java:159)
at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:119)
...
...
Caused by: java.lang.IllegalArgumentException: Cannot invokeorg.apache.shiro.realm.jdbc.JdbcRealm.setDataSource on bean class 'class org.apache.shiro.realm.jdbc.JdbcRealm' - argument type mismatch - had objects of type "org.apache.shiro.jndi.JndiObjectFactory" but expected signature "javax.sql.DataSource"
at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2235)
at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2151)
at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1957)
...
If instead I define an actual MySQL data source it works fine, e.g.
ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
ds.serverName = localhost
ds.user = root
ds.password = root
ds.databaseName = mydb
Any help is much appreciated.
This looks like it is likely a classpath issue. The stack trace references line numbers for ReflectionBuilder that make sense in shiro 1.1.0. However, they don't make sense in shiro 1.2.0. However, since JndiObjectFactory is new in shiro 1.2.0, and both classes are in shiro-core, it seems likely that you have both jars on the classpath.
You should first look in your war file, make sure that both jars aren't in there. If they are, you can fix your war file by removing the 1.1.0 version. If not, I would begin looking to see if you are inheriting an old version of shiro through the glassfish infrastructure somehow.
I am using jboss-5.0.1 GA.
I am trying to invoke EJB deployed on remote JBoss server from my local EJB using JNDI.
I have included the remote interfaces jar file in my local EJB project's class path. I have as well added jnp-client.jar, jboss-ejb3-client.jar in my class path.
I have started JBoss on remote machine with -b 0.0.0.0 flags to ensure it accepts remote connections.
Here is the code.
SatheBeanRemote sbr = null; //Is the remote interface for the remote bean
Properties p = new Properties();
p.put(Context.PROVIDER_URL, "jnp://10.73.17.76:1099"); //remote Jboss IP
p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
Context context;
try {
context = new InitialContext(p);
sbr = (SatheBeanRemote) context.lookup("RemoteEAR/SatheBean/remote");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I am getting the below exception.
javax.ejb.EJBException: Unexpected Error
java.lang.NoClassDefFoundError: com/netapp/beans/SatheBeanRemote
at com.netapp.balaji.greeting.GreetingBean.sayGreeting(GreetingBean.java:78)
Can anyone help me point out the issue ?
Probably, You have to add EJB Project in your client folder's class path, It may resolve the problem