如何在Java代码中访问JBoss Fuse中另一个Bundle的OSGI DataSource引用
Hey there! Let's break down exactly how to access your myDataSource reference and execute database queries in your Java code. Here are the most common and reliable approaches:
1. Inject via Blueprint XML Configuration
This is the standard Blueprint way to wire your DataSource into a Java bean:
Step 1: Update your Blueprint XML
Add a <bean> definition for your Java class, and inject the myDataSource reference using the <property> tag:
<!-- Your existing DataSource reference --> <reference id="myDataSource" filter="(osgi.jndi.service.name=myDataSource)" interface="javax.sql.DataSource" /> <!-- Define your data access bean and inject the DataSource --> <bean id="dataAccessService" class="com.yourcompany.service.MyDataAccessService"> <property name="dataSource" ref="myDataSource" /> </bean>
Quick note: Double-check your filter value—you wrote myDataSouce (missing an 'r') in your question. Make sure this matches the actual OSGi service name of your DataSource bundle, otherwise the reference won't resolve!
Step 2: Implement the Java Class
Add a setter method for the DataSource, then use it to create connections and run queries. Use try-with-resources to automatically clean up JDBC resources (avoids leaks):
package com.yourcompany.service; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MyDataAccessService { private DataSource dataSource; // Setter for Blueprint injection public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void runSampleQuery() throws SQLException { // Try-with-resources auto-closes Connection, PreparedStatement, ResultSet try (Connection conn = dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement("SELECT id, name FROM your_table"); ResultSet rs = stmt.executeQuery()) { while (rs.next()) { // Process each row of results int id = rs.getInt("id"); String name = rs.getString("name"); System.out.printf("Found record: ID=%d, Name=%s%n", id, name); } } } }
2. Inject via CDI @Inject Annotation
If your JBoss Fuse environment supports CDI (which it typically does), you can use annotations for cleaner code:
Step 1: Annotate Your Java Class
Use @Inject to wire the DataSource directly. Ensure your class is in a package that's scanned by Blueprint/CDI:
package com.yourcompany.service; import javax.inject.Inject; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MyDataAccessService { @Inject private DataSource myDataSource; // Name matches the reference ID in Blueprint public void runSampleQuery() throws SQLException { try (Connection conn = myDataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement("SELECT id, name FROM your_table"); ResultSet rs = stmt.executeQuery()) { while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.printf("Found record: ID=%d, Name=%s%n", id, name); } } } }
Step 2: Enable CDI in Blueprint (if needed)
If your bundle isn't already set up for CDI, add this to your Blueprint XML to enable component scanning:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:cdi="http://aries.apache.org/xmlns/cdi/v1.0.0"> <cdi:context/> <reference id="myDataSource" filter="(osgi.jndi.service.name=myDataSource)" interface="javax.sql.DataSource" /> </blueprint>
Key Tips
- Always use try-with-resources for JDBC objects to prevent resource leaks.
- Verify that your DataSource bundle is properly exported and active in the OSGi container (use
osgi:listandosgi:servicecommands in the Fuse console to check). - If you get a
NullPointerExceptionon the DataSource, double-check the filter in your<reference>tag and ensure the service is registered with the exactosgi.jndi.service.namevalue.
内容的提问来源于stack exchange,提问作者Julián

