I have created a JDBCProvider service in an IBM integration bus (IIB v10) in Windows called TESTDDBB, which is also the name of the database. I have a JavaCompute node where I'm trying to generate a connection to call an oracle function
TESTDDBB
connectionUrlFormat='jdbc:oracle:thin:#x.x.x.x:1521:TESTDDBB;'
connectionUrlFormatAttr1=''
connectionUrlFormatAttr2=''
connectionUrlFormatAttr3=''
connectionUrlFormatAttr4=''
connectionUrlFormatAttr5=''
databaseName='TESTDDBB'
databaseSchemaNames='PROM'
databaseType='Oracle'
databaseVersion='11.2.0.4.0'
description='default_Description'
environmentParms='default_none'
jarsURL='C:\jdbc\lib'
jdbcProviderXASupport='true'
maxConnectionPoolSize='200'
portNumber='1521'
securityIdentity='devCredentials'
serverName='x.x.x.x'
type4DatasourceClassName='oracle.jdbc.xa.client.OracleXADataSource'
type4DriverClassName='oracle.jdbc.OracleDriver'
useDeployedJars='true'
public class GetUserData_JavaCompute extends MbJavaComputeNode {
public void evaluate(MbMessageAssembly inAssembly) throws MbException {
...
Connection conn = getJDBCType4Connection("TESTDDBB",JDBC_TransactionType.MB_TRANSACTION_AUTO);
try(CallableStatement callableStmt = conn.prepareCall("{ ? = call PROM.pkg_prop_2.getUserData(?)}");) {
...
}
...
}
}
The problem is that when IIB tried to get the conenction, it isn't finding the datasource java class
...
com.ibm.broker.jdbctype4.jdbcdbasemgr.JDBCType4Connection#-53d4c850.createXAConnection 'java.lang.ClassNotFoundException: oracle.jdbc.xa.client.OracleXADataSource at java.net.URLClassLoader.findClass(URLClassLoader.java:609) at com.ibm.broker.classloading.JavaResourceClassLoader.findClass(JavaResourceClassLoader.java:181) at com.ibm.broker.classloading.SharedClassLoader.findClass(SharedClassLoader.java:215) at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:925)
...
I have the ojdbc6.jar driver in the folder C:\jdbc\lib and deployed in a shared library in the integration server, library that is referenced by the RESTAPI app that contains the JavaCompute node. What am I missing? I have tried using useDeployedJars true and false, and jarsURL also with 'C:\jdbc\lib\ojdbc6' without success. Where are the common libraries of the integration server in windows?
From one side you can place the jar to root of you java source folder and connect this jar to Integration Toolkit. This give you ability to use this jar. From other side you can configure JDBC provider for Integration node and use created alias in getJDBCType4Connection call. More information about working with databases from JavaCompute you can see here 1
Related
Am developing application using Maven it has EJB layer. I configured datasource in WebSphere Liberty server. All transaction can be handle by the server. Am using Jenkins to build a application. I would like to create CI/CD implementation. For that I tried add Junit test in application. but am unable to connect database while doing Jenkins build. Because there is no communication b/w server and Jenkins while doing build. How can I create Junit that handle database connection and EJB without Mock.?
One possible solution you could use here is an integration testing library called MicroShed Testing. It is created for integration tests with JavaEE/MicroProfile app servers such as Liberty, and can be used to test your application with external resources running such as DBs.
MicroShed Testing is ideal if you are running your Liberty application inside of a Docker container. If you are running in Docker, you can easily write an integration test that looks something like this:
#MicroShedTest
#SharedContainerConfig(AppContainerConfig.class)
public class DatabaseTest {
#Inject
public static MyJAXRSEndpoint personSvc;
#Test
public void testGetPerson() {
Long bobId = personSvc.createPerson("Bob", 24);
Person bob = personSvc.getPerson(bobId);
assertEquals("Bob", bob.name);
assertEquals(24, bob.age);
}
}
To get this working, you can define your application topology in the class referenced by the #SharedContainerConfig annotation like this:
public class AppContainerConfig implements SharedContainerConfiguration {
#Container
public static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>()
.withNetworkAliases("testpostgres")
.withDatabaseName("testdb");
#Container
public static MicroProfileApplication app = new MicroProfileApplication()
.withEnv("POSTGRES_HOSTNAME", "testpostgres")
.withEnv("POSTGRES_PORT", "5432")
.withAppContextRoot("/myservice");
#Override
public void startContainers() {
postgres.start();
app.start();
}
}
The above code will do the following steps:
1) Build your application into a Docker container, using the Dockerfile in your repo
2) Start up the docker container for your app AND the postgresql database (or any other DB container you may need)
3) Wait for containers to be ready, then run tests that invoke HTTP requests on the running containers
I find this approach nice because it works the same way anywhere Docker is installed -- either locally on your machine or in your CI/CD pipeline.
For more info on MicroShed Testing, I recommend checking out the website here:
https://microshed.org/microshed-testing/
and especially the examples, which include a Liberty+Database example:
https://microshed.org/microshed-testing/features/99_Examples.html
Disclaimer: I work on Liberty and MicroShed Testing
I am trying to connect to a Apache Ignite Server from a Spring Boot Application.
Example code:
ClientConfiguration cfg = new ClientConfiguration().setAddresses("127.0.0.1:10800");
try (IgniteClient client = Ignition.startClient(cfg)) {
Object cachedName = client.query(
new SqlFieldsQuery("SELECT name from Person WHERE id=?").setArgs("foo").setSchema("PUBLIC")
).getAll().iterator().next().iterator().next();
}
I get this error:
Caused by: class org.apache.ignite.IgniteCheckedException: Remote node
has peer class loading enabled flag different from local
[locId8=459833a1, locPeerClassLoading=true, rmtId8=83ea88ca,
rmtPeerClassLoading=false,
rmtAddrs=[ignite-0.ignite.default.svc.cluster.local/0:0:0:0:0:0:0:1%lo,
/10.4.2.49, /127.0.0.1], rmtNode=ClusterNode
[id=83ea88ca-da77-4887-9357-267ac7397767, order=1,
addr=[0:0:0:0:0:0:0:1%lo, 10.x.x.x, 127.0.0.1], daemon=false]]
So the PeerClassLoading needs to be deactivated in my Java code. How can I do that?
As noted in the comments, the error is from a thick client (or another server) connecting to the cluster but the code is from a thin client.
If you’re just reading/writing data and don’t need to execute code, the thin client is a perfectly good option.
To use a thick client, you need to make sure both the thick client and server have the same peer-class loading configuration. That would be either:
<property name=“peerClassLoadingEnabled” value=“false” />
in your Spring configuration file. Or:
IgniteConfiguration cfg = new IgniteConfiguration()
...
.setPeerClassLoadingEnabled(false);
(I’ve used false here as that’s your current server configuration. Having said that, you probably want it to be switched on.)
I have a web app running in Tomcat correctly that I want to run on the new OpenLiberty server, the app is starting correctly inside OpenLiberty but at the moment of the database connection initiation is throwing the following exception:
[Default Executor-thread-15] 2018-03-15 15:02:30 ERROR TomcatConnectionManager:41 - Loading jdbc/mysql/myaap failure
javax.naming.NameNotFoundException: java:/comp/env
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLName.<init>(JavaURLName.java:83)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLNameParser.parse(JavaURLNameParser.java:39)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLNameParser.parse(JavaURLNameParser.java:60)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext$NameUtil.<init>(JavaURLContext.java:474)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:321)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:370)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
The above exception is thrown during the lookup phase:
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
Is there any way to make it work on OpenLiberty doing less changes possible?
On OpenLiberty the equivalent lookup would look like this:
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
The key is that you need to use java:comp/... instead of java:/comp/...
The reason why Tomcat is different than Liberty is because Tomcat is just a servlet container and Liberty conforms to the full Java EE specification.
According to section EE.5.2.2 of the Java EE 7 spec:
The application component’s naming environment is composed of four logical
namespaces, representing naming environments with different scopes. The four
namespaces are:
java:comp – Names in this namespace are per-component (for example, per enterprise
bean). Except for components in a web module, each component gets
its own java:comp namespace, not shared with any other component. Components
in a web module do not have their own private component namespace.
See note below.
java:module – Names in this namespace are shared by all components in a
module (for example, all enterprise beans in a single EJB module, or all components
in a web module).
java:app – Names in this namespace are shared by all components in all modules
in a single application, where “single application” means a single deployment
unit, such as a single ear file, a single module deployed standalone, etc.
For example, a war file and an EJB jar file in the same ear file would both have
access to resources in the java:app namespace.
java:global – Names in this namespace are shared by all applications deployed
in an application server instance. Note that an application server instance
may represent a single server, a cluster of servers, an administrative
domain containing many servers, or even more. The scope of an application
server instance is product-dependent, but it must be possible to deploy multiple
applications to a single application server instance.
Had a similar problem going between WebSphere and Tomcat. I'm developing and testing on a Tomcat server and using utilities I can't change that handle the DB connection to our DB2. On WebSphere it uses a constant set to "jdbc/COMPDB2" to retrieve the DataSource when I configure Tomcat and my Web.xml file it resolves to "java:comp/env/jdbc/SFCCDB2"
My work around for on local work space it to add a listener to copy the resource to the level in the InitialContext. I'm not very experienced with the server side of things but this is working so far using TomEE 7.0.81.
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/SFCCDB2");
javax.naming.Context envCtx = (javax.naming.Context) ctx.lookup("java:comp/env");
try{
/*
Added this because after redeploying code to the server it would error
connecting to the DB with an SQLException Datasource is closed
*/
DataSource dataSource = (DataSource) ctx.lookup("jdbc/COMPDB2");
ctx.destroySubcontext("jdbc");
} catch (NamingException e){
//Doesn't exist; safe to just add
}
ctx.createSubcontext("jdbc");
ctx.bind("jdbc/COMPDB2", ds);
ctx.close();
I have been trying all day to connect to a Remote EJB on a Websphere Application Server 7. This configuration is necessary for project specific reasons. Its goal is to connect two applications together that are on independent EAR but on the same server.
I have been trying to access a dummy method that does not have any parameters.
The lookup URL is the one copied from the EJB deployment on my local server and it complies with EJB3.0 IBM specifications according to the information here.
I have seen several other posts on stackoverflow related to EJB Remote issues in WAS (but I cannot link all threads because of my user limitations) but they do not resolve or are not the same as my problem.
Local EJB invocation works fine.
Here is the implementation. I do not use any specific IBM WAS libraries in the imports:
The class that is connecting to the Remote EJB:
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL, "iiop://localhost:2809");
Context ctx = new InitialContext(env);
Object object = ctx.lookup("ejb/<component-id>#<package.qualified.interface>");
RemoteInterface interface = (RemoteInterface)javax.rmi.PortableRemoteObject.narrow(object, RemoteInterface.class);
String sResponse = (String)interface.dummy();
The definition of the remote interface is:
#Remote
public interface RemoteInterface {
public String dummy() throws Exception;
}
And my implementation is:
#Override
public String dummy() throws Exception {
return "string";
}
Environment information:
Websphere Application Server 7
JDK 1.6
EJB 3.0
EAR 5.0
Maybe someone can give me some pointers on what to do next.
I am working on jdbc connection and I am using eclipse. I have placed connection driver that is mysql-connector-java-5.1.6.jar file in WebContent/WEB-INF/lib folder. After that I am writing this code to simply create and test connection between application and driver
import java.lang.ClassNotFoundException;
public class implementation {
public static void main(String[]arg)
{
try
{
System.out.println("conneting to driver...");
Class.forName("com.mysql.jdbc.driver");
System.out.println("Connection Successful");
}
catch(ClassNotFoundException error)
{
System.out.println("Error:" + error.getMessage());
}
}
}
when I am running this program, I am getting this error.
connecting to driver.
Error:com.mysql.jdbc.driver
can you please help to solve this issue. thank you for giving me your important time.
You are getting ClassNotFoundException because the correct driver class name is com.mysql.jdbc.Driver and not com.mysql.jdbc.driver.
The 'D' of Driver is capital(standard Camel Case notation)
Hope this helps.
Add that jar file to BuildPath of the project.
Right Click on the project --> BuildPath -- Configure builaPath -->Add external jars.
Because You are not running a web application.
Class.forName("com.mysql.jdbc.driver");
By typing driver name manually like above, we are getting ClassNotFoundException because of small spell mistakes
That's why always better to use when the fully qualified class name is the input for method
for example,
Class.forName(Driver.class.getName().toString());
Before this we need to set the mysql-version.jar file into the buid path