3 Replies Latest reply on Mar 26, 2012 11:21 AM by benkirby

    How best to list JBoss AS 7 datasource properties in Java code?

    benkirby

      I'm running JBoss AS 7.1.0.CR1b. I've got several datasources defined in my standalone.xml e.g.

       

      {code:xml}

                  <subsystem xmlns="urn:jboss:domain:datasources:1.0">

                      <datasources>

                          <datasource jndi-name="java:/MyDS" pool-name="MyDS_Pool" enabled="true" use-java-context="true" use-ccm="true">

                              <connection-url>some-url</connection-url>

                              <driver>the-driver</driver>

                              [etc]

      {code}

      Everything works great.

       

      I'm trying to access the information contained here within my code - specifically the `connection-url` and `driver` properties.

       

      I've tried getting the Datasource from JNDI, as normal, but it doesn't appear to provide access to these properties:

       

      {code}

          // catches removed

          InitialContext context;

          DataSource dataSource = null;

          context = new InitialContext();

          dataSource = (DataSource) context.lookup(jndi);

      {code}

      ClientInfo and DatabaseMetadata from a Connection object from this Datasource also don't contain these granular, JBoss properties.

       

      My code will be running inside the container with the datasource specfied, so all should be available. I've looked at the IronJacamar interface

      {{org.jboss.jca.common.api.metadata.ds.DataSource}}

      , and its implementing class, and these seem to have accessible hooks to the information I require, but I can't find any information on how to create such objects with these already deployed resources within the container (only constructor on impl involves inputting all properties manually).

       

      JBoss AS 7's Command-Line Interface allows you to navigate and list the datasources as a directory system. http://www.paykin.info/java/add-datasource-programaticaly-cli-jboss-7/ provides an excellent post on how to use what I've been told is the Java Management API, but this appears to involve connecting to the target JBoss server externally:

       

      {code}

      ModelControllerClient client = ModelControllerClient.Factory.create(

                  InetAddress.getByName("127.0.0.1"), 9999);

      {code}

       

      My code is already running within that server, so I was hoping there was a way to achieve this without a connection. Can I inject an instance of some JBoss class which I can then query to get the populated IronJacamar objects, or similar? Or is the Management API the best way to get at them?

       

      Hope you can help, many thanks.

        • 1. Re: How best to list JBoss AS 7 datasource properties in Java code?
          jamezp

          This was answered on here http://stackoverflow.com/questions/9704715/how-to-list-jboss-as-7-datasource-properties-in-java-code, but I'll answer here too.

           

          What you're really trying to do is a management action. The best way to is to use the management API's that are available.

           

          Here is a simple standalone example:

           

          public class Main {
          
          
              public static void main(final String[] args) throws Exception {
                  final List<ModelNode> dataSources = getDataSources();
                  for (ModelNode dataSource : dataSources) {
                      System.out.printf("Datasource: %s%n", dataSource.asString());
                  }
              }
          
          
              public static List<ModelNode> getDataSources() throws IOException {
                  final ModelNode request = new ModelNode();
                  request.get(ClientConstants.OP).set("read-resource");
                  request.get("recursive").set(true);
                  request.get(ClientConstants.OP_ADDR).add("subsystem", "datasources");
                  ModelControllerClient client = null;
                  try {
                      client = ModelControllerClient.Factory.create(InetAddress.getByName("127.0.0.1"), 9999);
                      final ModelNode response = client.execute(new OperationBuilder(request).build());
                      reportFailure(response);
                      return response.get(ClientConstants.RESULT).get("data-source").asList();
                  } finally {
                      safeClose(client);
                  }
              }
          
          
              public static void safeClose(final Closeable closeable) {
                  if (closeable != null) try {
                      closeable.close();
                  } catch (Exception e) {
                      // no-op
                  }
              }
          
          
          
          
              private static void reportFailure(final ModelNode node) {
                  if (!node.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
                      final String msg;
                      if (node.hasDefined(ClientConstants.FAILURE_DESCRIPTION)) {
                          if (node.hasDefined(ClientConstants.OP)) {
                              msg = String.format("Operation '%s' at address '%s' failed: %s", node.get(ClientConstants.OP), node.get(ClientConstants.OP_ADDR), node.get(ClientConstants.FAILURE_DESCRIPTION));
                          } else {
                              msg = String.format("Operation failed: %s", node.get(ClientConstants.FAILURE_DESCRIPTION));
                          }
                      } else {
                          msg = String.format("Operation failed: %s", node);
                      }
                      throw new RuntimeException(msg);
                  }
              }
          }
          
          

           

          The only other way I can think of is to add module that relies on servers internals. It could be done, but I would probably use the management API first.

           

          --

          James R. Perkins

          • 2. Re: How best to list JBoss AS 7 datasource properties in Java code?
            benkirby

            Thanks James. I posted a slightly different version on here to see if other JBoss bods knew of any alternatives to the Management API approach, or whether this was indeed the only way to get the required info. We will see... If not, then your solution will be extremely helpful!

            • 3. Re: How best to list JBoss AS 7 datasource properties in Java code?
              benkirby

              Found the JBoss CLI public API (https://community.jboss.org/wiki/JBossAS7Command-linePublicAPI), which appears not to need the remote connection, but I can't currently upgrade to the JBoss version they recommend ("Since JBoss AS 7.1.1") . So have gone with your solution, James - thanks again for responding.