I am following these instructions here: Chapter 3. Additional Features - Red Hat Customer Portal
Specifically, I am trying to follow section 3.3 and get Kerberos working with a remoting application.
My standalone.xml looks like the example in the documentation. My service principal, keytab and user work, since I can follow section 3.2 and login through the management interface.
<security-realm name="krbRealm">
<server-identities>
<kerberos>
<keytab principal="remote/tmf-is3-sec.nsonet.com#NSONET.COM" path="tmfkrbrem.keytab" relative-to="jboss.server.config.dir" debug="true"/>
</kerberos>
</server-identities>
<authentication>
<kerberos remove-realm="true"/>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-domain name="krb-remoting-domain">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="realm" value="krbRealm"/>
</login-module>
</authentication>
<mapping>
<mapping-module code="SimpleRoles" type="role">
<module-option name="testuser" value="Users"/>
</mapping-module>
</mapping>
</security-domain>
<subsystem xmlns="urn:jboss:domain:remoting:3.0">
<endpoint/>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="krbRealm"/>
</subsystem>
I am using sample client code based on the client shown here: [JBEAP-715] EJB authentication via Kerberos does not work with wildfly-security-api - JBoss Issue Tracker
// Remoting
Context context = null;
try {
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("java.util.logging.manager", "java.util.logging.LogManager");
System.setProperty("java.util.logging.config.file", "logging.properties");
System.setProperty("java.util.logging.ConsoleHandler.level", "TRACE");
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, "http-remoting://tmf-is3-sec.nsonet.com:8080");
props.put("jboss.naming.client.ejb.context", true);
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
props.put("remote.connection.main.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS","true");
props.put("remote.connection.main.connect.options.org.xnio.Options.SSL_ENABLED", "false");
props.put("remote.connection.main.connect.options.org.jboss.remoting3.RemotingOptions.SASL_PROTOCOL", "remote");
context = new InitialContext(props);
} catch (Exception e) {
e.printStackTrace();
}
tmfService tmfBean = (tmfService) context.lookup("tmf-app/com.mentor.tmf.bean//tmfBean!com.mentor.tmf.api.internal.tmfService");
tmfRequest req = new tmfRequest("First test");
req.print();
tmfResponse resp = tmfBean.firstOperation(req);
resp.print();
}
Here is my bean:
#Stateless
#Remote(tmfService.class)
#SecurityDomain("krb-remoting-domain")
#RolesAllowed("Users")
public class tmfBean implements tmfService {
public tmfBean() {
// nothing here
}
#Override
public tmfResponse firstOperation(tmfRequest req) {
System.out.println("tmfBean gets request <" + req.getMyData() + ">\n");
tmfResponse rval = new tmfResponse(req.getMyData() + " MODIFIED");
return rval;
}
}
I get these errors on the client: (login is successful)
Exception in thread "main" javax.naming.AuthenticationException: Failed to connect to any server. Servers tried: [http-remoting://tmf-is3-sec.nsonet.com:8080 (Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication)] [Root exception is javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication]
at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:238)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:149)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:130)
at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:272)
at org.jboss.naming.remote.client.RemoteContext.lookupInternal(RemoteContext.java:104)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:93)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:146)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.mentor.tmf.client.tmfTest.main(tmfTest.java:154)
Caused by: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
GSSAPI: Server rejected authentication
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:114)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:389)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:241)
I get this error on the server:
08:06:12,851 INFO [stdout] (default I/O-1) Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator false KeyTab is C:\wildfly-10.0.0.Final\standalone\configuration\tmfkrbrem.keytab refreshKrb5Config is false principal is remote/tmf-is3-sec.nsonet.com#NSONET.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
08:06:12,853 INFO [stdout] (default I/O-1) principal is remote/tmf-is3-sec.nsonet.com#NSONET.COM
08:06:12,853 INFO [stdout] (default I/O-1) Will use keytab
08:06:12,854 INFO [stdout] (default I/O-1) Commit Succeeded
08:06:12,854 INFO [stdout] (default I/O-1)
08:06:13,029 TRACE [org.jboss.remoting.remote.server] (default task-2) Server sending authentication rejected: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)]
at com.sun.security.sasl.gsskerb.GssKrb5Server.evaluateResponse(Unknown Source)
at org.jboss.sasl.gssapi.GssapiServer$1.run(GssapiServer.java:60)
at org.jboss.sasl.gssapi.GssapiServer$1.run(GssapiServer.java:56)
... 27 more
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.EncryptedData.decrypt(Unknown Source)
... 19 more
Caused by: java.security.GeneralSecurityException: Checksum failed
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(Unknown Source)
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes128.decrypt(Unknown Source)
... 22 more
Any assistance would be appreciated. We cannot find any documentation on how to authenticate a client with Kerberos to access an EJB.
thanks,
-Tom
I found the solution. Basically the service principal needs to have both remoting/... and remote/.. in the name for the same account.
I only had "remote/..." in one account and "remoting/..." in another test account. I deleted the duplicate test account an added "remoting/..." to the service account.
C:>setspn -a remoting/tmf-is3-sec.nsonet.com tmfkrbrem
Registering ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com
remoting/tmf-is3-sec.nsonet.com
Updated object
The result should look like this:
C:>setspn -l tmfkrbrem
Registered ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com:
remoting/tmf-is3-sec.nsonet.com
remote/tmf-is3-sec.nsonet.com
Then I created a new keytab, but this may not be needed.
C:>ktpass -princ remote/tmf-is3-sec.nsonet.com#NSONET.COM -pass Test1234 -mapuser NSONET\tmfkrbrem -
ptype KRB5_NT_PRINCIPAL -crypto AES128-SHA1 -kvno 0 -out C:\Users\Administrator\Desktop\tmfkrbrem.keytab
Targeting domain controller: nso-dc.nsonet.com
Using legacy password setting method
Successfully mapped remote/tmf-is3-sec.nsonet.com to tmfkrbrem.
Key created.
Output keytab to C:\Users\Administrator\Desktop\tmfkrbrem.keytab:
Keytab version: 0x502
keysize 75 remote/tmf-is3-sec.nsonet.com#NSONET.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x11 (AES128-SHA1) keylength
16 (0x9477d8bdfbf874ae5ad0b24fd611fb30)
Related
I have moved from spring 4.x to 5.2.0 and to camel 2.21.0,
during the patching process of the packages,
rabbitmq client began to throw the following exceptions:
com.rabbitmq.client.impl.ForgivingExceptionHandler
An unexpected connection driver error occurred (Exception message: Connection reset)
Connection failed, will retry in 5000ms
java.io.IOException
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:126)
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:122)
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:362)
at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:64)
at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:99)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:944)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:903)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:861)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1044)
at org.apache.camel.component.rabbitmq.RabbitMQEndpoint.connect(RabbitMQEndpoint.java:228)
at org.apache.camel.component.rabbitmq.RabbitMQConsumer.openConnection(RabbitMQConsumer.java:64)
at org.apache.camel.component.rabbitmq.RabbitMQConsumer.getConnection(RabbitMQConsumer.java:75)
at org.apache.camel.component.rabbitmq.RabbitConsumer.reconnect(RabbitConsumer.java:307)
at org.apache.camel.component.rabbitmq.RabbitMQConsumer$StartConsumerCallable.call(RabbitMQConsumer.java:216)
at org.apache.camel.component.rabbitmq.RabbitMQConsumer$StartConsumerCallable.call(RabbitMQConsumer.java:196)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.rabbitmq.client.ShutdownSignalException: connection error
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36)
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:494)
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:306)
... 16 more
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:288)
at com.rabbitmq.client.impl.Frame.readFrom(Frame.java:91)
at com.rabbitmq.client.impl.SocketFrameHandler.readFrame(SocketFrameHandler.java:164)
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:580)
... 1 more
the RouteBuilder is like the following:
String conStr = "rabbitmq:sheker?hostname=%s"
+"&portNumber=%s"
+"&username=%s"
+"&password=%s"
+"&queue=%s"
+"&routingKey=%s"
+"&autoDelete=false"
+"&concurrentConsumers=%d";
from(String.format(conStr, hostname, port, username, password, queueName, queueName, queueConcurrentConsumers))
.throttle(throttleRequestCount)
.timePeriodMillis(throttleInterval)
.bean(Processor.PROCESSOR_BEAN_NAME);
the consumer is NOT created and messages are NOT coming through - and that IOException occurs - how can I fix that?
EDIT:
I think the issue is that my rabbit is working only over SSL connection,
so I tried the following:
<rabbit:connection-factory
id="defaultConnectionFactory"
channel-cache-size="5"
addresses="${addresses}"
password="${password}"
username="${username}"
connection-factory="sslConnectionFactory"/>
<bean id="sslConnectionFactory" class="com.sheker.MySSLConnectionFactory">
<constructor-arg>
<value>${useSsl}</value>
</constructor-arg>
<constructor-arg>
<value>${keystore}</value>
</constructor-arg>
<constructor-arg>
<value>${cert}</value>
</constructor-arg>
<beans:property name="requestedHeartbeat" value="60"/>
</bean>
import com.rabbitmq.client.ConnectionFactory;
public class MySSLConnectionFactory extends ConnectionFactory {
public SSLConnectionFactory(final boolean useSsl, final String keystore, final String cert) {
if (useSsl) {
useSslProtocol(new HttpUtil(keystore, cert).createSslContext());
}
}
}
String connectionStr = "rabbitmq:sheker?"
+"queue=%s"
+"&autoDelete=false"
+"&concurrentConsumers=%d"
+"&connectionFactory=#defaultConnectionFactory";
but I get even more exceptions:
{"filename":"RabbitMQConsumer.java","lineno":"222","stacktrace":"java.net.ConnectException: Connection refused (Connection refused)\n\tat java.net.PlainSocketImpl.socketConnect(Native Method)\n\tat java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)\n\tat java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)\n\tat java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)\n\tat java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)\n\tat java.net.Socket.connect(Socket.java:589)\n\tat com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:60)\n\tat com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:62)\n\tat com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:99)\n\tat com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:944)\n\tat com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:903)\n\tat com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:861)\n\tat com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1044)\n\tat org.apache.camel.component.rabbitmq.RabbitMQEndpoint.connect(RabbitMQEndpoint.java:231)\n\tat org.apache.camel.component.rabbitmq.RabbitMQConsumer.openConnection(RabbitMQConsumer.java:64)\n\tat org.apache.camel.component.rabbitmq.RabbitMQConsumer.getConnection(RabbitMQConsumer.java:73)\n\tat org.apache.camel.component.rabbitmq.RabbitConsumer.reconnect(RabbitConsumer.java:311)\n\tat org.apache.camel.component.rabbitmq.RabbitMQConsumer$StartConsumerCallable.call(RabbitMQConsumer.java:218)\n\tat org.apache.camel.component.rabbitmq.RabbitMQConsumer$StartConsumerCallable.call(RabbitMQConsumer.java:198)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\n\tat java.lang.Thread.run(Thread.java:748)","level":"INFO","exception_class":"java.net.ConnectException","logger_name":"org.apache.camel.component.rabbitmq.RabbitMQConsumer","thread":"Camel (camel) thread #5 - RabbitMQConsumer","message":"Connection failed, will retry in 5000ms","timestamp":"2020-11-24 15:52:30,674","exception_message":"Connection refused (Connection refused)"}
Requirement : Create a multi-tenant Application which should insert each tenants data into their respective PDBs based on the tenant id in the request. In other words each tenant or customer will have there own PDB in a CDB, all PDBs will have the same schema and based on then tenant Id in the request a datasource will be selected and the data would be inserted into that PDB.
Stack - spring boot 2.3.0.RELEASE, Oracle 18c, Connection pool - Oracle shared universal connection pool
UCP connection :
<ucp-properties>
<connection-pool
connection-pool-name="pool1"
connection-factory-class-name="oracle.jdbc.pool.OracleDataSource"
url="jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=orcl.accounts.intern)))"
user="C##commonuser"
password="commonuser"
initial-pool-size="10"
min-pool-size="5"
max-pool-size="20"
connection-repurpose-threshold="13"
sql-for-validate-connection="select 1 from dual"
shared="true"
>
<connection-property name="oracle.jdbc.ReadTimeout" value="2000"/>
<connection-property name="oracle.net.OUTBOUND_CONNECT_TIMEOUT" value="2000"/>
<data-source data-source-name="pdbcust1" service="pdbcust1.accounts.intern" user="cust1" password="password"/>
<data-source data-source-name="pdbcust2" service="pdbcust2.accounts.intern" user="cust2" password="password"/>
</connection-pool>
</ucp-properties>
Spring datasource config class :
#Bean
public DataSource dataSource() throws SQLException {
System.setProperty("oracle.ucp.jdbc.xmlConfigFile", "file:/" + dbConfigProperties.getUcpConfigFile());
final AbstractRoutingDataSource dataSource = new MultitenantRoutingDataSource();
targetDataSources = new ConcurrentHashMap<>();
final PoolDataSource tenantDataSource1 = getTenantDataSource("pdbcust1", "cust1", "password");
final PoolDataSource tenantDataSource2 = getTenantDataSource("pdbcust2", "cust2", "password");
targetDataSources.put("pdbcust1", tenantDataSource1 );
targetDataSources.put("pdbcust2", tenantDataSource2 );
dataSource.setDefaultTargetDataSource(lTenantDataSource2);
lDataSource.setTargetDataSources(lTargetDataSources);
lDataSource.afterPropertiesSet();
return lDataSource;
}
private static PoolDataSource getTenantDataSource(final String tenantId, String username, String password) {
try {
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(tenantId);
Properties prop = new Properties();
// prop.setProperty("user", username);
// prop.setProperty("password", password);
//pds.reconfigureDataSource(prop);
return pds;
} catch (final Exception e) {
e.printStackTrace();
}
return null;
}
Above configuration does not work and throws the following error when I fire a request with a tenant id :
java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:550) ~[ojdbc8-19.3.0.0.jar:19.3.0.
However if I uncomment the following lines in the above class and remove the username and password from the UCP file, it works:
prop.setProperty("user", username);
prop.setProperty("password", password);
pds.reconfigureDataSource(prop);
So my questions are :
Why does this happen?
The UCP config xmls xsd has a user and password field, how do we use it?
This page describes share pooling https://docs.oracle.com/middleware/12213/wls/JDBCA/shared_pooling_ds.htm#JDBCA-GUID-4B7DA858-327E-4CEA-A68C-376792D4A466
This has line : "This common user must exist in all PDBs that are connected to the sharing data sources"
What does it mean?
In order to use ucp shared pool feature, the database user must be same for all the datasources sharing a common pool of connection. So you should not use user and password under datasource element.
<data-source data-source-name="pdbcust1" service="pdbcust1.accounts.intern" />
<data-source data-source-name="pdbcust2" service="pdbcust2.accounts.intern"/>
If you have a requirement to use a different user for each pdb then shared pool is not an option. In that case you should define two different pools in the XML, one for each PDB, that means you should not set the shared=true in connection-pool element. Also, for non shared pools there is no need of using a common user at pool level, you can directly use pdb user, password and service name under pool element.
<ucp-properties>
<connection-pool
connection-pool-name="pool1"
connection-factory-class-name="oracle.jdbc.pool.OracleDataSource"
url="jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=cust1.accounts.intern)))"
user="cust1"
password="cust1password"
initial-pool-size="10"
min-pool-size="5"
max-pool-size="20"
sql-for-validate-connection="select 1 from dual"
>
<connection-property name="oracle.jdbc.ReadTimeout" value="2000"/>
<connection-property name="oracle.net.OUTBOUND_CONNECT_TIMEOUT" value="2000"/>
<data-source data-source-name="pdbcust1" />
</connection-pool>
<connection-pool
connection-pool-name="pool2"
connection-factory-class-name="oracle.jdbc.pool.OracleDataSource"
url="jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=pdbcust2.accounts.intern)))"
user="cust2"
password="cust2password"
initial-pool-size="10"
min-pool-size="5"
max-pool-size="20"
sql-for-validate-connection="select 1 from dual"
>
<connection-property name="oracle.jdbc.ReadTimeout" value="2000"/>
<connection-property name="oracle.net.OUTBOUND_CONNECT_TIMEOUT" value="2000"/>
<data-source data-source-name="pdbcust2" />
</connection-pool>
</ucp-properties>
trying to add content to infinispan cache and I get null pointer exception when i use the put method. Mine is a JSF web application. We are trying to achieve session replication using wildfly 13.
import org.infinispan.Cache;
public class index extends AbstractPageBean implements java.io.Serializable {
#Resource(lookup = "java:jboss/infinispan/cache/web/web_repl")
Cache<String, String> ilsCache;
public Cache<String, String> getCache() {
return ilsCache;
}
public void prerender() {
ilsCache.put("Message", "Hello");
logger.info("CACHE " + getCache());
}
Log file
2018-08-21 14:21:57,134 ERROR [biz.autoscan.ils.index] (default task-1) index.java::Exception occured : java.lang.NullPointerException
at biz.autoscan.ils.index.btnLogin_action(index.java:930)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:181)
at com.sun.el.parser.AstValue.invoke(AstValue.java:289)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
at java.lang.Thread.run(Thread.java:745)
Any idea why I still get null pointer exception fro cache.put()?
Edit: We are using WildFly 13 in domain mode and Infinispan in replication mode. My aim is to store the session object in the infinispan cache and share it between all the nodes.
Infinispan subsystem in domain.xml: This is how I have configured infinispan. We are using only two servers at the moment hence we have gone with replication mode.
<subsystem xmlns="urn:jboss:domain:infinispan:6.0">
<cache-container name="web" aliases="ilsee" default-cache="web_repl" module="org.wildfly.clustering.web.infinispan">
<transport channel="ee" lock-timeout="60000"/>
<local-cache name="Username"/>
<replicated-cache name="web_repl">
<transaction mode="BATCH"/>
</replicated-cache>
<distributed-cache name="dist">
<transaction mode="NON_XA"/>
<file-store/>
</distributed-cache>
</cache-container>
</subsystem>
The answer depends on how you configure your server.
I will provide a generic example.
First, you need to configure your standalone.xml file
<subsystem xmlns="urn:infinispan:server:core:9.2">
<cache-container module="org.infinispan.extension:ispn-9.2" name="infinispan_container" default-cache="default">
<transport/>
<global-state/>
<distributed-cache name="default"/>
<distributed-cache name="myCache"/>
</cache-container>
</subsystem>
Then in your Java application, you need to inject the resource using
#Resource(lookup = "java:jboss/datagrid-infinispan/container/infinispan_container/cache/myCache")
Cache cache;
As you can see infinispan_container and myCache are values that you provided in the XML configuration file.
There are two possible ways for your application to utilize Infinispan within Wildfly: embedded mode and server mode.
You can find more information http://infinispan.org/docs/stable/user_guide/user_guide.html#usage_3
I'm using sun-jms-adapter.rar. All my configuration works fine before starting to use authentication. I also tried accessing to queue from a standalone application and stateless bean (this is used to send messages to queue), and all works fine.
My actual configuration is:
weblogic-ds.xml
<connection-factories>
<!-- SUN JMS JCA Resource adapter, use this to get transacted JMS in beans -->
<no-tx-connection-factory>
<jndi-name>CFX/ExternalConnectionFactory</jndi-name>
<xa-transaction />
<rar-name>sun-jms-adapter.rar</rar-name>
<connection-definition>javax.jms.QueueConnectionFactory</connection-definition>
<config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property>
<config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/DefaultJMSProvider</config-property>
<config-property name="Destination" type="java.lang.String">javax.jms.Destination</config-property>
<max-pool-size>20</max-pool-size>
<depends>jboss.messaging:service=ServerPeer</depends>
</no-tx-connection-factory>
</connection-factories>
ejb-jar.xml configuration:
<enterprise-beans>
<message-driven>
<ejb-name>QueueReceiverMDB</ejb-name>
<ejb-class>com.tests.mdb.QueueReceiverMDB</ejb-class>
<transaction-type>Bean</transaction-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>destination</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.queue.in}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>ConnectionURL</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.url}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>UserName</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.username}</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>Password</activation-config-property-name>
<activation-config-property-value>${weblogic.jms.password}</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
and finally my jboss.xml:
<message-driven>
<ejb-name>QueueReceiverMDB</ejb-name>
<destination-jndi-name>java:/CFX/ExternalConnectionFactory</destination-jndi-name>
<local-jndi-name>local/QueueReceiverMDB</local-jndi-name>
<resource-adapter-name>sun-jms-adapter.rar</resource-adapter-name>
<configuration-name>JMSJCA Message Driven Bean</configuration-name>
</message-driven>
I'm allways getting this error:
16:25:07,126 WARNING [Activation] JMSJCA-E016: [sync-QueueReceiver(jms/TestJMSQueueIn) # [t3://localhost:7001]]: message delivery initiation failed (attempt #1); will retry in 1 seconds. The error was: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.dispatcher.DispatcherAdapter.convertToJMSExceptionAndThrow(DispatcherAdapter.java:110)
at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:45)
at weblogic.jms.client.JMSSession.consumerCreate(JMSSession.java:2982)
at weblogic.jms.client.JMSSession.setupConsumer(JMSSession.java:2749)
at weblogic.jms.client.JMSSession.createConsumer(JMSSession.java:2691)
at weblogic.jms.client.JMSSession.createReceiver(JMSSession.java:2596)
at weblogic.jms.client.WLSessionImpl.createReceiver(WLSessionImpl.java:991)
at com.stc.jmsjca.core.RAJMSObjectFactory.createMessageConsumer(RAJMSObjectFactory.java:620)
at com.stc.jmsjca.core.SyncDelivery$SyncWorker.init(SyncDelivery.java:502)
at com.stc.jmsjca.core.SyncDelivery.start(SyncDelivery.java:202)
at com.stc.jmsjca.core.Activation.asyncStart(Activation.java:557)
at com.stc.jmsjca.core.Activation.access$000(Activation.java:82)
at com.stc.jmsjca.core.Activation$1.run(Activation.java:351)
at java.lang.Thread.run(Thread.java:745)
Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.dispatcher.DispatcherAdapter.convertToJMSExceptionAndThrow(DispatcherAdapter.java:110)
at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:45)
at weblogic.jms.frontend.FEConsumer.(FEConsumer.java:296)
at weblogic.jms.frontend.FESession$2.run(FESession.java:1076)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
at weblogic.jms.frontend.FESession.consumerCreate(FESession.java:1072)
at weblogic.jms.frontend.FESession.invoke(FESession.java:3027)
at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:961)
at weblogic.messaging.dispatcher.DispatcherServerRef.invoke(DispatcherServerRef.java:276)
at weblogic.messaging.dispatcher.DispatcherServerRef.handleRequest(DispatcherServerRef.java:141)
at weblogic.messaging.dispatcher.DispatcherServerRef.access$000(DispatcherServerRef.java:34)
at weblogic.messaging.dispatcher.DispatcherServerRef$2.run(DispatcherServerRef.java:111)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.dispatcher.Request.handleThrowable(Request.java:87)
at weblogic.jms.dispatcher.Request.getResult(Request.java:52)
at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:1124)
at weblogic.messaging.dispatcher.DispatcherImpl.syncRequest(DispatcherImpl.java:185)
at weblogic.messaging.dispatcher.DispatcherImpl.dispatchSync(DispatcherImpl.java:220)
at weblogic.jms.dispatcher.DispatcherAdapter.dispatchSync(DispatcherAdapter.java:43)
... 13 more
Caused by: weblogic.jms.common.JMSSecurityException: Access denied to resource: type=, application=TestJMSModule, destinationType=queue, resource=TestJMSQueueIn, action=receive
at weblogic.jms.common.JMSSecurityHelper.checkPermission(JMSSecurityHelper.java:162)
at weblogic.jms.backend.BEDestinationSecurityImpl.checkReceivePermission(BEDestinationSecurityImpl.java:87)
at weblogic.jms.backend.BEConsumerImpl.init(BEConsumerImpl.java:312)
at weblogic.jms.backend.BEConsumerImpl.(BEConsumerImpl.java:268)
at weblogic.jms.backend.BEQueueImpl.createConsumer(BEQueueImpl.java:188)
at weblogic.jms.backend.BESessionImpl.createBEConsumer(BESessionImpl.java:469)
at weblogic.jms.backend.BESessionImpl.createConsumer(BESessionImpl.java:479)
at weblogic.jms.backend.BESessionImpl.invoke(BESessionImpl.java:297)
at weblogic.messaging.dispatcher.Request.wrappedFiniteStateMachine(Request.java:961)
... 16 more
Any suggestion is welcome...
I found a solution to my problem, could not be the best one, but it works.
After spent lots of time trying put this working, I checkout the source code of resource adaptor (sun-jms-adapter.rar) from here, and found a possible error. They don't put credentials in initialContext and close context after creating session. So I modify this stepts, by adding "Context.SECURITY_PRINCIPAL" and "Context.SECURITY_CREDENTIALS" to context, and leave it open. And this really works. All this in getJndiObject method in RAWLObjectFactory class.
If someone finds another way, and a best way, please share... because they are putting credentials when creating queue Connection, so may be a bug at weblogic source.
I leave the modified code:
private Object getJndiObject(UrlParser url, String name, String username, String password) throws JMSException {
if (sLog.isDebugEnabled()) {
sLog.debug("Looking up JNDI object " + name);
}
if (name == null || name.length() == 0) {
throw Exc.jmsExc(LOCALE.x("E401: The JNDI name is null"));
}
InitialContext ctx = null;
try {
if (mSpecialISORBMethod != null) {
// Works on IS only
if (mSpecialISORBMethodIsOn != null) {
Boolean isEnabled = (Boolean) mSpecialISORBMethodIsOn.invoke(null, new Object[0]);
if (!isEnabled.booleanValue()) {
throw Exc.rsrcExc(LOCALE.x("E823: CORBA-SE needs to be enabled on"
+ " this server. Please change the value of the <se-orb enabled=\"false\"/>"
+ " to <se-orb enabled=\"true\"/> in the configuration file of "
+ " the Integration Server (logicalhost/is/domains/<domain-name>"
+ "/config/domain.xml) and restart the server."));
}
}
final Properties prop = (Properties) mSpecialISORBMethod.invoke(null, new Object[0]);
prop.put(Context.URL_PKG_PREFIXES, JNDI_WEBLOGIC_PROTOCOL_PACKAGES);
ctx = new InitialContext(prop);
return ctx.lookup("corbaname:iiop:1.2#" + url.getHost() + ":" + url.getPort()
+ '#' + name);
} else {
// Will be executed on other application servers than the IS
//add username/password if not null to context
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, "t3://" + url.getHost() + ":" + url.getPort());
if (username != null) {
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
}
ctx = new InitialContext(env);
return ctx.lookup(name);
}
} catch (Exception e) {
throw Exc.jmsExc(LOCALE.x("E821: Could not find JNDI object by name [{0}]: {1}", name, e), e);
}
//leave context open
/*finally {
safeClose(ctx);
}*/
}
I'm trying to Directly instantiating JMS Resources without using JNDI to a REMOTE HORNETQ.
I am running my test code in Eclipse IDE. Setup my classpath to use the HornetQ 2.2.5 libraries.
The target HornetQ is version 2.1.2.Final, I figured they should be backwards compatible, maybe im wrong?
Okay, so I have read the online documentation and followed the examples on connecting to a remote JMS server without using JNDI. I keep on getting the following exception. Im not sure what Im missing but I believe I have everything setup correctly. Could someone please point out what Im missing here? Thanks in advance.
JMSException: Failed to create session factory
The connector on hornetq-configuration.xml is:
<connector name="netty">
<factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
<param key="host" value="${10.100.111.222}"/>
<param key="port" value="${hornetq.remoting.netty.port:5445}"/>
</connector>
The acceptor is:
<acceptor name="netty">
<factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
<param key="host" value="${10.100.111.222}"/>
<param key="port" value="${hornetq.remoting.netty.port:5445}"/>
</acceptor>
My Test code is:
Connection connection = null;
try
{
Queue queue = HornetQJMSClient.createQueue("TESTQ");
Map<String, Object> connectionParams = new HashMap<String, Object>();
connectionParams.put(TransportConstants.PORT_PROP_NAME, 5445);
connectionParams.put(TransportConstants.HOST_PROP_NAME, "10.100.111.222");
TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(),
connectionParams);
ConnectionFactory factory = (ConnectionFactory) HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
System.out.println("debug: " + factory.getClass());
connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);
TextMessage message = session.createTextMessage("This is a test message");
System.out.println("Sent message: " + message.getText());
producer.send(message);
}
finally
{
if (connection != null)
{
try {
connection.close();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I get the following Exception
SEVERE: Failed to create netty connection
java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at org.jboss.netty.channel.socket.oio.OioClientSocketPipelineSink.connect(OioClientSocketPipelineSink.java:114)
at org.jboss.netty.channel.socket.oio.OioClientSocketPipelineSink.eventSunk(OioClientSocketPipelineSink.java:74)
at org.jboss.netty.channel.Channels.connect(Channels.java:541)
at org.jboss.netty.channel.AbstractChannel.connect(AbstractChannel.java:218)
at org.jboss.netty.bootstrap.ClientBootstrap.connect(ClientBootstrap.java:227)
at org.jboss.netty.bootstrap.ClientBootstrap.connect(ClientBootstrap.java:188)
at org.hornetq.core.remoting.impl.netty.NettyConnector.createConnection(NettyConnector.java:450)
at org.hornetq.core.client.impl.ClientSessionFactoryImpl.getConnection(ClientSessionFactoryImpl.java:1016)
at org.hornetq.core.client.impl.ClientSessionFactoryImpl.getConnectionWithRetry(ClientSessionFactoryImpl.java:897)
at org.hornetq.core.client.impl.ClientSessionFactoryImpl.connect(ClientSessionFactoryImpl.java:212)
at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:602)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:611)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:121)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:116)
at com.ws.proto.ManualJMS.main(ManualJMS.java:39)
Oct 19, 2011 1:18:50 PM org.hornetq.core.logging.impl.JULLogDelegate warn
WARNING: Tried 1 times to connect. Now giving up on reconnecting it.
Exception in thread "main" javax.jms.JMSException: Failed to create session factory
at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:615)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:121)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:116)
at com.ws.proto.ManualJMS.main(ManualJMS.java:39)
Caused by: HornetQException[errorCode=2 message=Cannot connect to server(s). Tried with all available servers.]
at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:619)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:611)
... 3 more
Regarding compatibility: We didn't have client compatibility until 2.2.5+. If you try client on 2.2.2 and server at 2.2.5, you will probably get a version mismatch exception.
We are aiming to always be compatible from 2.2.5+
And you have a typo in your config:
<connector name="netty">
<factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
<param key="host" value="10.100.111.222"/>
<param key="port" value="${hornetq.remoting.netty.port:5445}"/>
</connector>
We use a syntax for properties and default values. You could for instance define a variable MY_IP and use it as:
"${MY_IP:10.100.111.222}"
If MY_IP is null, you would get 10.100.111.222
But "${10.100.111.222}" doesn't mean anything.