TestContainers Oracle TimeoutException - java

I tried to use testcontainers library for integration tests with Oracle. Here is is the simple test:
public class SimpleTest {
#Rule
public OracleContainer oracle = new OracleContainer();
#Test
public void simpleTest() throws SQLException {
HikariDataSource ds = buildHikariDataSource();
Statement statement = ds.getConnection().createStatement();
statement.execute("SELECT 1 FROM dual");
ResultSet resultSet = statement.getResultSet();
resultSet.next();
int resultSetInt = resultSet.getInt(1);
assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
}
private HikariDataSource buildHikariDataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl(oracle.getJdbcUrl());
hikariConfig.setUsername(oracle.getUsername());
hikariConfig.setPassword(oracle.getPassword());
return new HikariDataSource(hikariConfig);
}
}
But it fails with TimeoutException:
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:256)
at org.testcontainers.containers.GenericContainer.lambda$start$0(GenericContainer.java:184)
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:76)
... 18 more
Caused by: org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:53)
at org.testcontainers.containers.JdbcDatabaseContainer.waitUntilContainerStarted(JdbcDatabaseContainer.java:81)
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:235)
... 20 more
My Docker installation is suitable with testcontainers-oracle-xe and os is macOS Sierra 10.12.6.
How can this problem be resolved?
P.S. Full console output

All in all I created an issue in testcontainers-java-module-oracle-xe repository.
The solution was to change location to US and language to English in System Preferences.
The answer from testcontainers engineer:
My colleague have faced the same problem. We have debugged and
understood that problem with oracle TNS (ORA-12514). In order to
resolve it, there is a need to change language to English and location
to US.

Related

How to test JdbcPagingItemReaderBuilder with Junit

I'm creating a spring-batch application, and I'm having trouble creating a unit test class with junit that tests my reader that uses JdbcPaginItemReaderBuilder.
Reader Code:
#Configuration
public class RelatorioReader {
#Bean("relatorioreader")
#StepScope
public ItemReader<Relatorio> relatorioItemReader(
#Qualifier("dataSource") DataSource dataSource,
#Value("#{jobParameters[dateParam]}") String dateParam) {
return new JdbcPagingItemReaderBuilder<Relatorio>()
.name("relatorioDiario")
.dataSource(dataSource)
.selectClause("SELET * ")
.fromClause("FROM myTable ")
.whereClause(" WHERE date = :dateParam")
.parameterValues(Collections.singletonMap("dateParam", dateParam))
.sortKeys(Collections.singletonMap("ID", Order.ASCENDING))
.rowMapper(new RelatorioMapper())
.build();
}
}
Junit Code
#ExtendWith(MockitoExtension.class)
public class RelatorioReaderTest {
#InjectMocks
RelatorioReader reader;
#Mock
DataSource dataSource;
#Test
public void test_itemReader() {
ItemReader<Relatorio> itemReader = reader.relatorioItemReader(dataSource, "2023-02-16");
assertNotNull(itemReader);
}
}
Exception when running Junit:
java.lang.IllegalArgumentException: Unable to determine PagingQueryProvider type
at org.springframework.batch.item.database.builder.JdbcPagingItemReaderBuilder.determineQueryProvider(JdbcPagingItemReaderBuilder.java:383)
at org.springframework.batch.item.database.builder.JdbcPagingItemReaderBuilder.build(JdbcPagingItemReaderBuilder.java:335)
at com.erico.relatorio.item.reader.RelatorioReader.relatorioItemReader(RelatorioReader.java:34)
at com.erico.relatorio.item.reader.RelatorioReaderTest.test_itemReader(RelatorioReaderTest.java:27)
...
Caused by: org.springframework.jdbc.support.MetaDataAccessException: Could not get Connection for extracting meta-data; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: DataSource returned null from getConnection(): dataSource
at ...
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: DataSource returned null from getConnection(): dataSource
at ...
When you do not specify a paging query provider, the builder will try to determine a suitable one from the meta-data of your data source. Since you are using a mocked database, you need to mock the call to getConnection(). Otherwise, you have to use a stub database for tests (like an embedded H2 or HSQL).
If you know what datasource you will be using, the best way is to specify its paging query provider implementation in your builder. Here is an example if you use H2:
#Configuration
public class RelatorioReader {
#Bean("relatorioreader")
#StepScope
public ItemReader<Relatorio> relatorioItemReader(
#Qualifier("dataSource") DataSource dataSource,
#Value("#{jobParameters[dateParam]}") String dateParam) {
return new JdbcPagingItemReaderBuilder<Relatorio>()
.name("relatorioDiario")
.dataSource(dataSource)
.selectClause("SELET * ")
.fromClause("FROM myTable ")
.whereClause(" WHERE date = :dateParam")
.parameterValues(Collections.singletonMap("dateParam", dateParam))
.sortKeys(Collections.singletonMap("ID", Order.ASCENDING))
.rowMapper(new RelatorioMapper())
.queryProvider(new H2PagingQueryProvider())
.build();
}
}

Obtain an OracleDataSource in SpringBoot 2

Is it possible to retrieve a OracleDataSource from the default SpringBoot 2 Hikari connection pool using a NamedParameterJdbcTemplate object?
Using Java 8, Oracle 11g (ojdbc6-11.2.0.1.jar) and gradle
This is what i've tried.
#Repository
public class MyClass{
#Autowired
NamedParameterJdbcTemplate jdbcTemplate;
public void myMethod(){
try{
//OracleDataSource ods = new OracleDataSource(); // This works but is obviously not Spring
OracleDataSource ods = (OracleDataSource) jdbcTemplate.getJdbcTemplate().getDataSource(); // This fails
ods.setURL(url);
ods.setUser(user);
ods.setPassword(pass);
...
catch(Exception e){
System.out.println("In Exception");
e.printStackTrace();
}
}
}
Application.properties:
spring.datasource.url=jdbc:oracle:thin:#//${ORA_HOST}:${ORA_PORT}/${ORA_SID}
spring.datasource.username=${USER}
spring.datasource.password=${PASS}
Error message:
In Exception
java.lang.ClassCastException: com.zaxxer.hikari.HikariDataSource cannot be cast to oracle.jdbc.pool.OracleDataSource
I don't think this is possible (or neccessary). The easiest way is to unwrap() a connection object, which has already connected to the dB:
Connection conn = this.jdbcTemplate.getJdbcTemplate().getDataSource().getConnection().unwrap(OracleConnection.class);
Just a query like, how are you able to get OracleConnection.class, because in my case I get squiggly line underneath OracleConnection.class and there are no packages available to import.

java.lang.NoSuchMethodError: org.apache.hive.service.cli.TableSchema

I am trying to connect to hive using Java. This is my code. I am running it in Eclipse Oxygen. My Java version is 8.
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException
{
try
{
Class.forName(driverName);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
System.exit(1);
}
Connection con = DriverManager.getConnection("jdbc:hive2://<ip>:<port>/database", "username", "password");
String sql = "select * from tablename";
Statement stmt = con.createStatement();
stmt.executeQuery(sql);
}
I am able to create table and insert data into table using the above method. But whenever I try to retrieve data from table it throws the following error.
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hive.service.cli.TableSchema.<init>(Lorg/apache/hive/service/cli/thrift/TTableSchema;)
Given below are the jars I am using. They have the classes given in the error.
commons-logging-1.2
curator-client-2.0.0-incubating
hadoop-common-2.7.3
hadoop-common-3.1.0
hive-exec-3.0.0
hive-jdbc-1.1.0
hive-metastore-3.0.0
hive-service-1.1.0
hive-service-3.0.0
hive-service-rpc-2.1.0
httpclient-4.5.6
httpcore-4.4.10
libfb303-0.9.3
libthrift-0.9.3
log4j-1.2.17
slf4j-api-1.8.0-beta2
Please help me.
The error might be caused by incompatible library versions. You have multiple jar versions of the same libs in your project. Therefore at runtime it will not be clear switch one is used.
get rid of the duplicates and use only the newer versions of hadoop-common, hive-service.

MS Sql Login failed for user

I have java app with Hikari connection pool to MSSql databse.
It works perfect when i use my database, but when i want to connect to remote database i get error: Login failed for user. I saw some problems about this here but did not found the solution. I tried to change the port on MSSQL and etc but did not succeeded.
Error message:
Caused by: com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: Login failed for user 'user'. ClientConnectionId:a45173d9-e047-49a1-b8d0-e8507ad2a7b9
at com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:544)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:536)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:112)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:72)
at com.mypackage.DAOConnPool.<clinit>(DAOConnPool.java:33)
... 2 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'user'. ClientConnectionId:a45173d9-e047-49a1-b8d0-e8507ad2a7b9
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:258)
at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:256)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:108)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:4290)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:3157)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$100(SQLServerConnection.java:82)
at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:3121)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7151)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2478)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2026)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:1687)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1528)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:866)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnectionInternal(SQLServerDataSource.java:968)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnection(SQLServerDataSource.java:78)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:356)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:199)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:444)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:515)
... 5 more
Here is my config:
mssql.connectionstring= jdbc:sqlserver://IP:1433;databaseName=object_registry;integratedSecurity=true;
mssql.jdbcdriver =com.microsoft.sqlserver.jdbc.SQLServerDataSource
mssql.user = user
mssql.pass = password
mssql.minConnectionPerPartition = 5
mssql.maxConnectionPerPartition = 10
mssql.partitionCount=1
Here is my connection:
try (Connection conn = DAOConnPool.getConnection(); Statement statement = conn.createStatement();) {
statement.executeUpdate(db_statement);
Here is DAOConnPool class:
public class DAOConnPool {
private static HikariConfig config = new HikariConfig();
private static HikariDataSource dataSource;
static {
config.setDataSourceClassName(ConfigurationFile.getProperty("mssql.jdbcdriver"));
config.setJdbcUrl(ConfigurationFile.getProperty("mssql.connectionstring"));
config.setUsername(ConfigurationFile.getProperty("mssql.user"));
config.setPassword(ConfigurationFile.getProperty("mssql.pass"));
//config.addDataSourceProperty("cachePrepStmts", "true");
//config.addDataSourceProperty("prepStmtCacheSize", "250");
//config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
dataSource = new HikariDataSource(config);
}
}
public DAOConnPool() {
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
Try to remove :
config.setDataSourceClassName(ConfigurationFile.getProperty("mssql.jdbcdriver"));
I think you are trying to connect to the database remotely using windows authentication. In connection string this
integratedSecurity=true
define that you are connecting via windows authentication. If you want to connect via network you should give the appropriate privilege. If you are connecting server authentication, you need to remove that attribute from your connecting string.

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

Categories

Resources