When I deploy 2 packages with Spring AMQP I get JMX error in the below code:
#Bean
public CachingConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(HOST);
connectionFactory.setBeanName("Test_123");
return connectionFactory;
}
I error Caused by: javax.management.InstanceAlreadyExistsException: org.springframework.amqp.rabbit.connection:name=connectionFactory,type=CachingConnectionFactory
Full error stack:
https://pastebin.com/CdU3epMz
How I can set unique name for connectionFactory?
EDIT:
I also tried to place application.properties under src/main/java/resources this configuration:
spring.jmx.enabled=false
spring.datasource.jmx-enabled=false
spring.jmx.default-domain=ssds # JMX domain name.
spring.jmx.server=apiServer # MBeanServer bean name.
management.metrics.export.jmx.domain=metccriddcs # Metrics JMX domain name.
management.metrics.export.jmx.enabled=false # Whether exporting of metrics to JMX is enabled.
management.endpoints.jmx.exposure.exclude=*
But I get the same error.
The solution:
... implements ObjectNamingStrategy {
#Override
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
Class managedClass = AopUtils.getTargetClass(managedBean);
String domain = ClassUtils.getPackageName(managedClass);
Hashtable<String, String> properties = new Hashtable<>();
properties.put("type", ClassUtils.getShortName(managedClass));
properties.put("name", "asdsdsd");
// ensure the application name is included as a property in the object name
properties.put("app", "api");
return ObjectNameManager.getInstance(domain, properties);
}
}
Related
So I've been trying to find out solution to this from long ! Any insights would help !
I am getting following error
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name
'routerConnectionFactory' defined in class path resource
[com/CONFIDENTIAL/event/processor/configuration/EventsConfiguration.class]: Unsatisfied dependency expressed through method 'routerConnectionFactory' parameter 0; nested exception is
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named
'actionRouterConnectionFactory' is expected to be of type 'org.apache.activemq.ActiveMQConnectionFactory' but
was actually of type 'org.springframework.cloud.sleuth.instrument.messaging.LazyTopicConnectionFactory'
Code snippet
#Bean(name = "routerConnectionFactory")
#Primary
public CachingConnectionFactory routerConnectionFactory(ActiveMQConnectionFactory actionRouterConnectionFactory ){
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setTargetConnectionFactory(actionRouterConnectionFactory);
return cachingConnectionFactory;
}
#Bean
public ActiveMQConnectionFactory actionRouterConnectionFactory(
#Value("${confidential.gateway.message.broker.url}") String brokerURL,
#Value("${confidential.router.message.broker.user.name}") String userName,
#Value("${confidential.router.message.broker.user.password}") String password,
#Value("true") Boolean alwaysSyncSend, RedeliveryPolicy defaultEntry,
#Value("${shared.amq.keystore.path:#{null}}") String keyStorePath,
#Value("${shared.amq.keystore.password:#{null}}") String keyStorePassword) throws Exception {
ActiveMQSslConnectionFactory targetConnectionFactory= new ActiveMQSslConnectionFactory();
targetConnectionFactory.setBrokerURL(brokerURL);
targetConnectionFactory.setUserName(userName);
targetConnectionFactory.setPassword(password);
if(!StringUtils.isEmpty(keyStorePath) && !StringUtils.isEmpty(keyStorePassword)){
targetConnectionFactory.setTrustStore(keyStorePath);
targetConnectionFactory.setTrustStorePassword(keyStorePassword);
}
targetConnectionFactory.setAlwaysSyncSend(alwaysSyncSend);
targetConnectionFactory.setRedeliveryPolicy(defaultEntry);
return targetConnectionFactory;
}
spring-cloud-sleuth-core : 2.2.6.RELEASE
spring-cloud-sleuth-zipkin : 2.2.6.RELEASE
active-mq-broker, active-mq-camel, client, jms-pool , open-wire-legacy, pool, spring : 5.15.13
other spring boot and related dependencies : 2.2.6.RELEASE
https://edwin.baculsoft.com/2019/07/error-overriding-bean-of-same-name-declared-in-class-path-resource-when-integrating-spring-cloud-sleuth-and-activemq-library/
Referred multiple articles on this issue (also on StackoverFlow), also tried disabling sleuth but didn't help !
Any clue ?
Your method signatures are looking for 'ActiveMQConnectionFactory'-- that is tightly coupled to ActiveMQ. Most likely, the intetion is to couple to JMS API instead. Change code to use javax.jms.ConnectionFactory instead. (ActiveMQConnectionFactory implements javax.jms.ConnectionFactory)
I am migrating our application to openjdk11 and with this setup my application is throwing below error.
PLease help on this
Note : With Jdk 1.8 the same code and configurations are working fine .
Java version: openjdk 11
Springboot-hadoop : 2.4.0 RELEASE
application properties
spring.hadoop.fsshell.enabled=false
#hadoop security properties
hadoop.config.key=hadoop.security.authentication
hadoop.config.value=Kerberos
#Hive connection properties
hive.datasource.keytab=/config/security/sit.001.keytab
hive.datasource.drivername=org.apache.hive.jdbc.HiveDriver
hive.datasource.username=ssit.001
#hive.datasource.password=password
hive.truststore.file=/config/security/hivetrust.jks
hive.krb5.conf=/config/security/krb5.conf
hive.datasource.url=url
hive.krb5.conf.debug.prop=sun.security.krb5.debug
hive.krb5.conf.isdebug=true
Java changes
#Value("${hive.datasource.drivername}")
private String driverName;
#Value("${hive.datasource.url}")
private String jdbcUrl;
#Value("${hive.datasource.username}")
private String userId;
#Value("${hive.datasource.keytab}")
private String keytab;
#Value("${hive.krb5.conf}")
private String kerberosConf;
#Value("${hadoop.config.key}")
public String hadoopConfigKey;
#Value("${hadoop.config.value}")
public String hadoopConfigValue;
#Bean(name = "hiveDS")
public DataSource configureHiveDataSource() throws IOException, ClassNotFoundException, SQLException {
Connection con = null;
// System.setProperty("hadoop.home.dir", hadoopHome);
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("java.security.krb5.conf", kerberosConf);
org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
conf.set(hadoopConfigKey, hadoopConfigValue);
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(userId, keytab);
Class.forName(driverName);
con = DriverManager.getConnection(jdbcUrl);
LOGGER.info("Hive Db Connected");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverName);
dataSource.setUrl(jdbcUrl);
return dataSource;
}
#Bean(name = "hiveJdbc")
public JdbcTemplate getHiveJdbcTemplate(#Qualifier("hiveDS") DataSource hiveDS) {
return new JdbcTemplate(hiveDS);
}
#Bean(name = "hiveNamedJdbc")
public NamedParameterJdbcTemplate getHiveNamedJdbcTemplate(#Qualifier("hiveDS") DataSource hiveNamedDS) {
return new NamedParameterJdbcTemplate(hiveNamedDS);
}
}
2021-04-28T21:18:18.829+0530 [main] ERROR o.s.d.h.c.c.a.AbstractConfiguredAnnotationBuilder - Failed to perform build. Returning null
java.lang.IllegalArgumentException: Bean name must not be null
at org.springframework.util.Assert.notNull(Assert.java:201)
Error creating bean with name 'hadoopConfiguration' defined in class path resource [org/springframework/data/hadoop/config/annotation/configuration/SpringHadoopConfiguration.class]: Bean instantiation via factory method failed; nested exception is **org.springframework.beans.BeanInstantiationException: Failed to instantiate **[org.apache.hadoop.conf.Configuration]: Factory method 'configuration' threw exception; nested exception is java.lang.NullPointerException
I am having this small message producer:
public static void main(String[] args) throws Exception {
BasicConfigurator.configure();
Properties env = new Properties();
InputStream is = Producer.class.getResourceAsStream("/jms.properties");
env.load(is);
Context context = new InitialContext(env);
ConnectionFactory factory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
Destination queue = (Destination) context.lookup("jms/demoQueue");
JMSContext jmsContext = factory.createContext();
jmsContext.createProducer().send(queue, "Message");
}
Using the following properties:
java.naming.factory.initial = org.wildfly.naming.client.WildFlyInitialContextFactory
java.naming.provider.url = http-remoting://localhost:8080
java.naming.security.principal = alex
java.naming.security.credentials = password
messagingProvider = demo
connectionFactoryNames = QueueFactory
queue.queueReq = jms.queueReq
queue.queueResp = jms.queueResp
But I get an exception:
"Caused by: javax.jms.JMSSecurityException: AMQ119031: Unable to
validate user"
I believe I have misconfigured something on the server. But what exactly? Security settings have pattern: # with role guest and admin. I don't see anything else related to security
Call the overloaded createContext() method with 2 arguments:
JMSContext context = factory.createContext("alex", "password");
Then it should work if the "alex" user has correct role assigned.
I remember I had a discussion with developers about how the createContext() should work (it was in relation with Elytron - the new securtity subsystem), and the decission for now was like: It works as designed, but it can be enhanced in the future.
See comments in JBEAP-10527 for details.
How to use JMX MBean for HikariCP in Spring boot application? I have a code like this:
#SpringBootApplication
public class App() { ... }
And other class:
#Configuration
public class DatabaseCfg() {
#Bean
#ManagedOperation
public DataSource ds (#Value("${hikari.proprerties}") String config) {
HikariConfig hikariConfig = new HikariConfig(config);
return new HikariDataSource(hikariConfig);
}
In Java Mission Control (or JMX Console) a saw only Datasource managed bean, not JMX MBean for HikariCP (link). Is it possible to add it too?
In Spring Boot 2.0+ you can set the register-mbeans property in your application.properties file
spring.datasource.hikari.register-mbeans = true
If you are using an earlier version of Spring Boot you will also have to set the datasource
spring.datasource.type = com.zaxxer.hikari.HikariDataSource
I believe on your hikariConfig you need to set a few additional settings. You need to register the MBeans and set a pool name on the configuration.
HikariConfig hiakriConfig = new HikariConfig(config);
hikariConfig.setRegisterMbeans(true);
kikariConfig.setPoolName("my-pool-1");
Yes you obviously could drive these through the properties as well. I'm not sure if you are including these in your properties file as they are not listed. Also please note you are spelling properties wrong (#Value("${ds.proprerties}") should probably should be (#Value("${ds.properties}") but I'm not sure how you actually have named variables and property files. You may want to double check if that is where you want to set all of the properties.
Try this. Exclude your Hiakri DataSource Bean from being registered by Spring.
#Resource
private ObjectProvider<MBeanExporter> mBeanExporter;
#Bean("dataSource")
public DataSource createDataSource() {
String url = hikariDataSourceConfig.getUrl();
String username = hikariDataSourceConfig.getUsername();
String password = hikariDataSourceConfig.getPassword();
long idleTimeoutInMilliSeconds =
hikariDataSourceConfig.getIdleTimeOutInMilliseconds();
long maxLifetimeInMilliseconds =
hikariDataSourceConfig.getMaxLifetimeInMilliseconds();
int maximumPoolSize = hikariDataSourceConfig.getMaximumPoolSize();
int minimumIdle = hikariDataSourceConfig.getMinimumIdle();
String poolName = "HikariDataSource";
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setRegisterMbeans(true);
hikariConfig.setJdbcUrl(url);
hikariConfig.setUsername(username);
hikariConfig.setPassword(password);
hikariConfig.setIdleTimeout(idleTimeoutInMilliSeconds);
hikariConfig.setMaxLifetime(maxLifetimeInMilliseconds);
hikariConfig.setMaximumPoolSize(maximumPoolSize);
hikariConfig.setMinimumIdle(minimumIdle);
hikariConfig.setPoolName(poolName);
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
mBeanExporter
.ifUnique((exporter) -> exporter.addExcludedBean("dataSource"));
return 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