Ethereum JCA Resource Adapter Project

This project delivers a standard Java EE JCA Resource Adapter to connect to Ethereum networks.

Tested Java EE application servers:

  • JBoss EAP 6.4.24
  • JBoss EAP 7.4.8
  • JBoss WildFly 26.1.2.Final
  • Oracle WebLogic 12.2.1.3.0

Tested Ethereum client nodes:

  • go-ethereum 1.10.26
  • Hyperledger Besu 20.10.4

We should be able to support every Java EE 6+ application server.

We target the Java EE JCA version 1.6 specification and Java 8+.

If you like this project, please consider a donation at:

0x0c56073db91c2Ba57FF362301eb32262BBeE6147

Features

Why would you want to use such a thing as a JCA Resource Adapter to connect to an Ethereum network?

What does it offer more compared to direct usage of the web3j library?

Transaction support

This JCA Resource Adapter gives you transaction support within your Java EE application when transmitting Ethereum transactions towards an Ethereum network.

Simply use the JCA Connector, and you will automatically have transaction support within your Java EE application.

Example code:

@Resource(name = "EthereumConnectionFactory")
private EthereumConnectionFactory ethereumConnectionFactory;

try (EthereumConnection ethereumConnection = this.ethereumConnectionFactory.getConnection()) {
    ethereumConnection.sendRawTransaction(rawTransaction);
}

The transaction implementation also features automatic retry on commit just in case the client node is temporarily unavailable.

The JCA Resource Adapter even supports JCA transactions on smart contracts written in Solidity.

Furthermore, fast Ethereum transactions are also supported via internal nonce caching. On a JCA rollback, the corresponding nonce cache gets nicely reset as well.

Message Listener

We provide a robust message listener API that features automatic recovery from a failed client node.

Example code:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "nodeLocation", propertyValue = "ws://127.0.0.1:8546"),
    @ActivationConfigProperty(propertyName = "wsOrigin", propertyValue = "http://localhost"),
    @ActivationConfigProperty(propertyName = "deliverPending", propertyValue = "true"),
    @ActivationConfigProperty(propertyName = "deliverBlock", propertyValue = "true"),
    @ActivationConfigProperty(propertyName = "omitSyncing", propertyValue = "true")
})
public class EthereumMDB implements EthereumMessageListener {

    @Override
    public void pendingTransaction(String transactionHash, Date timestamp) throws Exception {
        
    }

    @Override
    public void block(String blockHash, Date timestamp) throws Exception {
        
    }

    @Override
    public void connectionStatus(boolean connected) throws Exception {
        
    }
}

The resource adapter will automatically attempt to reconnect when a client node goes down for a while. Hence your client node can go down for maintenance without the need to restart your Java EE application server.

Notice that the message listener supports web sockets besides plain HTTP connections. It is advised to use web sockets instead of plain HTTP connections to reduce the stress on the Ethereum client node.

Transaction Monitoring

Given the nature of blockchain, you probably want to monitor the Ethereum transactions as they get mined (or not). To ease this task, we provide an EthereumTransactionManager CDI bean. Simply inject this CDI bean as follows:

import be.e_contract.ethereum.utils.EthereumTransactionManager;

@Inject
private EthereumTransactionManager ethereumTransactionManager;

Instruct the EthereumTransactionManager to monitor an Ethereum transaction via:

String yourTransactionHash = "...";
this.ethereumTransactionManager.monitorTransaction(yourTransactionHash);

And observe the state of the Ethereum transaction via:

private void observeEthereumEvent(@Observes EthereumPublicationEvent event) {
  // do something here, depending on the event outcome...
}

Gas Price Oracle

We provide a modular gas price oracle.

Of course we provide a default gas price oracle, next to the client node gas price oracle, that allows you to ask for a gas price given a maximum duration you're willing to wait for the transaction to be mined within the Ethereum network.

Example code:

@EJB
private GasPriceOracle gasPriceOracle;

Integer maxDurationInSeconds = 60;
String oracle = "default";
BigInteger gasPrice = this.gasPriceOracle.getGasPrice(oracle, maxDurationInSeconds);

Depending on your max duration, this gas price oracle gives you a gas price that is on average 30-50% lower than the gas price set by the client node.

JSF Tag Library

The project delivers a JSF Tag Library for validation and conversion of Ethereum types.

Example input validation of an Ethereum address:

xmlns:eth="urn:be:e-contract:ethereum:jsf"

<h:inputText value="...">
    <eth:addressValidator/>
</h:inputText>

Example conversion from wei to ether:

xmlns:eth="urn:be:e-contract:ethereum:jsf"

<h:outputText value="1234">
    <eth:fromWei unit="ETHER"/>
</h:outputText>