I have a Spring app running in WebLogic. In my DAO, it inherits a base class with a method that returns a "javax.sql.DataSource". I inject that datasource indirectly using the "jee:jndi-lookup" in my Spring application context to get the datasource from JNDI. When I look at this in the debugger, it appears to be a "weblogic.jdbc.common.internal.RmiDataSource".
I'd like to figure out how I can introspect into that datasource in my code to determine information about the database I'm connected to, particularly the host, port, SID, and username. Is there any way I could do that?
For some background, I have extensive diagnostics in my app for troubleshooting db connection and query issues. It would be very helpful if at runtime, I could introspect information about the WebLogic datasource from the database connection in use.
As I described, I already determined in the debugger what the actual type was, and I've examined all the obvious properties in that object for casting or reflection opportunities, and I don't see any obvious indications of information like "host", "port", or "SID".
I think you can use reflection and call all the getter methods of this class.
That should get you some helpful information. But based on the name of this class,
it looks like it's an internal WebLogic class and it's not really designed for this.
Still, you can do it with reflection, you can even call private getter methods with reflection.
Java Reflection API
The "right" JEE approach is not caring about these low-level details in code. After finding out which DataSource doesn't work, troubleshooting problems involves only application server logs and application server configuration tweaks.
There are several good reasons for insulating applications from DataSource details:
you aren't supposed to lose track of what abstract data sources you are using; using more than one DataSource (in fact, more than one Connection) in the same class is extremely unusual.
permanent data source configurations have been defined by you in your application server configuration, they are not secret or hidden.
transient data source state, on the other hand, is accessible through application server tools and logs.
on the third hand, data source implementations are proprietary and need to be freely optimized; expecting them to provide useful information is unreasonable.
your application is unlikely to be able to fix a troublesome data source; if it could, it would be able to mess with other applications in the same application server.
"replacing" a data source with another doesn't make any sense.
any scenario in which you want the definition of data source to vary according to circumstances should be dealt with by other means, mostly close to the DBMS (for example, if DBMS processes or machines are subject to shutdowns and restarts you could configure the servers as a cluster sharing the same IP address; relatively easy with Oracle).
Related
I have used MySqlDataSource for in jdbc connectivity.I have used following code
MysqlDataSource d = new MysqlDataSource();
d.setUser("user");
d.setPassword("pass");
d.setServerName("hostname.com");
d.setDatabaseName("db");
Connection c = d.getConnection();
Also i have searched there is an option of Configuring a MySQL Datasource in Apache Tomcat.
Is there any performance difference between these two? which one is best to use?
Configuring Datasource in tomcat will help you to share same data source between applications running in same tomcat. that Datasource will be managed by container (tomcat in your case).
while the Datasource created in code will be created by your application and can be used by that application only.
So if you have multiple application running on tomcat and accessing same data source, that configuring Datasource in tomcat will be good approach and have performance factor because only one data source is created and not having separate connections for each application
But if you have only single application that the first approach you have used is good one
They both use the internally the same driver, i dont think the performance is much different here, i guess if you need to access teh database only at that place and the enduser isn't supposed to use his own authentication you may use it directly from java, but if you will need the connectivity on different places it could be helpful to configure this using apache configuration, specially that if anything changes like database server, user name or whatever you don't need to get in the code to change it, this could be very important if end users have to set their own configurations.
The improvement of configuring a pool of Connections (as the one provided by tomcat) is mainly that you will actually create and close a lot less of connections.
When using a pool, when you request a Connection to a pool it will look if it has any connection already created and available for reuse and, if it has, it will provide you with it (instead of creating a new Connection, which is a heavy operation). You must still close() a Connection provided by Tomcat so Tomcat knows that it can now reuse when it is requested again.
Additionally, the advantage of the pool is that your code does not need to know the configuration data for the Connection. He just requests a Connection from a given pool and the sysadmin configures it, allowing for greater flexibility (the sysadmin does not need to know how to configure your app, just how to configure the Tomcat which is fairly more standard).
I'd like to know if is possible to store an object with data into a JNDI resource, like we can do in sessions, to share the data (login data) between different applications. I've read the doc in http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html but I'm still a bit confused due to the instantiation process of the JNDI. Thanks!
Tomcat's JNDI service is very lightweight, and intentionally provides isolation between webapps. The implementation also does not support remote connections and references, etc. So you won’t be able to share data between servers in a cluster.
If you don't want to use a fully-featured Jakarta EE container (like Eclipse Glassfish or Wildfly) then you might want to look into something like webcache to share data like this.
I have a an appliction running on the WebSphere application server (7.0.0.19), using DB2 database (9.5). I have the impression that the application server or the database ignores the isolation level which is set in the application (in the Java code). The application uses gets the connections from the application server, it uses the transaction manager from the application server.
I did not find a clear answer (or acknowledgement), not in the manuals, not on the web. I found some indications, suggestions, insinuations, but no clear answers. Some monitoring on the database seams to prove this.
Can someone acknowledge this behaviour?
Can this be changed using configuration?
Since the data source is managed by the application server (and WebSphere is a full featured implementation of Java EE), it's actually the JCA spec that applies here. Section 7.9 of the JCA 1.5 imposes the following restrictions on the ability of an application to change the transaction isolation level:
If a connection is marked as shareable, it must be transparent to the application whether a single shared connection is used or not. The application must not make assumptions about a single shared connection being used, and hence must use the connection in a shareable manner.
However, a J2EE application component that intends to use a connection in an unshareable way must leave a deployment hint to that effect, which will prevent the connection from being shared by the container. Examples of unshareable usage of a connection include changing the security attributes, isolation levels, character settings, and localization configuration.
To summarize: in general, your application should not attempt to change the isolation level if the resource reference configures the connection as shareable. If you look at the Requirements for setting data access isolation levels topic in the WAS infocenter, you will also find the following statement:
Trying to directly set the isolation level through the setTransactionIsolation() method on a shareable connection that runs in a global transaction is not allowed. To use a different isolation level on connections, you must provide a different resource reference.
On the other hand, section 7.9.1 of the JCA 1.5 spec describes scenarios where an app server may still allow an application to change the isolation level, even if the connection is shareable. Basically this applies to scenarios where the connection is configured as shareable, but where it is effectively not shared (because there is no need to share the connection between multiple components).
The Extensions to data access APIs topic in the infocenter suggests that WebSphere supports this:
applications [...] cannot modify the properties of a shareable connection after making the connection request, if other handles exist for that connection. (If no other handles are associated with the connection, then the connection properties can be altered.)
Therefore you should be able to use setTransactionIsolation() to change the isolation level in particular scenarios, but this depends on how your application uses the connection.
Finally, you didn't describe in detail how you monitored that at the database level, but you need to take into account that at some point the app server needs to reset the isolation level on the physical connection. Therefore, if setTransactionIsolation() succeeds, the change may be in effect only for a short time on the physical connection.
Note that there are a couple of ways to avoid all these complications (that may or may not be applicable in your case):
Instead of using setTransactionIsolation(), configure the appropriate isolation level on the resource reference, and if necessary use multiple resource references.
Use the WebSphere specific WSDataSource API to specify the expected isolation level before acquiring the connection.
Modify your SQL to change the isolation level on a per query basis (e.g. use WITH UR).
http://www.ibm.com/developerworks/java/library/j-isolation/index.html this is relevant
also ejb transactions and isolation level discussion applies
http://java.boot.by/ibm-287/ch05.html
I want to configure a self-written JCA 1.6 inbound resource adapter (RA). My big problem is that the RA needs to get access to some (dynamic) configuration data living in the application that uses the RA.
Now I know that this is against the original idea of the whole JCA idea but unfortunately I cannot change this design as quickly as I'd like/have to.
The data I need to get to the RA is
the port it's supposed to listen on,
the license used for the whole application (the feature the RA supplies requires extra licensing)
additional configuration data stored in a db
I've come up with four ideas:
Use the asadmin create-resource-adapter-config. Due to the fact that glassfish doesn't seem to restart apps depending on the RA, we need to restart the application after this. While this attempt is suitable for the port, it won't fit for the other data.
Use administered objects to give my application a means to pass data in to the RA. This idea is mentioned here. I guess this does it, but the spec states in chapter 13.4.2.3 that
Note, administered objects are not used for setting up asynchronous message
deliveries to message endpoints. The ActivationSpec JavaBean is used to hold all
the necessary activation information needed for asynchronous message delivery
setup.
But I cannot get any dynamic data to the ActivationSpec object (neither through a DeploymentDescriptor nor through annotations). Or did I miss something here? :-)
Use JDBC directly to access the data (also grabbed the idea from here). While this is presumably the best idea, it does not work for the mentioned licensing data as it is not stored in the db.
The last idea I had was to put a method in the MessageDrivenBean (through my interface) that is used to fetch data from within the RA. That method could be called from the RA and would supply the data. But: I just think that is quite abusive as it couples the RA to the app.
Dear community, what are your thoughts on this one? I'm afraid it's not so easy to find answers to these questions, so I'd be quite happy about opinions!
Thanks and cheers,
Julius
In the ra.xml there is the possibility to define config-properties. In Websphere these then show up as editable fields in a table of custom properties for the selected resource adapter. I'm working on a similar problem, I also need to pass hostname / port info to an RA. Unfortunately I haven't figured out how to read the contents of these fields from within the RA however.
The solution I finally came up with is to use the #ConfigProperty annotation. This means I use option one of my question above.
So my ResourceAdapter class looks like this:
public class Hl7ResourceAdapter implements ResourceAdapter {
#ConfigProperty
private Integer port = null;
// Rest from ResourceAdapter interface omitted here...
// Use port here to open socket...
}
The #ConfigProperty fields can now be set through either
a resource-adapter-config
the ra.xml deployment descriptor
Now in order to reconfigure these settings I use glassfish's REST interface to change these settings programmatically (one could also use the asadmin create-resource-adapter-config command). I circumvent the problem, that glassfish does not restart the application that uses the resource adapter by simply restarting it myself through REST. (To be precise: I disable the application and then reenable it to get around another bug in glassfish)
A few additional notes:
We deploy the resource adapter's .rar file into the .ear of the application using it.
We have a separate application outside glassfish (standalone) that calls the REST interface to do such things as restart the resource adapter application etc. It is obvious that an application cannot restart itself properly.
Hope this helps. kutuzof, will this get you any further?
I have some code that I want to make public. The code sends email via servers, connects to databases, and other tasks requiring usernames/passwords.
I'd like to store the passwords and such in a seperate configuration file so that I don't have to sanitize my code on every commit.
How can I do this? It would be easy to do in C using #define, but I'm not sure how to accomplish this in Java.
EDIT: The environment I'm using is Glassfish
The basic method is put the information in a properties file and use the Properties class to load it at run time. If you're using a J2EE server, database connections are configured in the server and the code references them by an abstract name.
I think I should add that if you're using a server, how to configure it and how to get the connections to your code will vary by server and J2EE level so post your environment. Using the Properties class is pretty obvious just by looking at the javadoc and the load() methods.
In glassfish, go to the admin console and under Resources create a new connection pool. That defines your database connection and will share a pool of those connections among your applications. Now under JDBC Resources, create a new entry that maps that pool to a name. The name is usually something like jdbc/myappname.
For a J2EE5 or later application, you can now add this as a class level variable:
#Resource(mappedName="jdbc/myappname") DataSource myDS;
At runtime the server will inject that resource to your database pool. Then when you need a connection, you can do this inside any method:
Connection conn = myDS.getConnection();
The result is your code doesn't have to care at all about the database connection information or managing a pool of connections. You can deploy the identical code on development and production servers, and they will get an appropriate connection. In order to get the injection, it has to be a class the server creates like an EJB, servlet, tag library handler, or JSF managed bean.