Skip to Main Content

Java and JavaScript in the Database

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Same java stored procedure works slow on first instance and fast on second instance (node)

PeterValencicJun 1 2018 — edited Aug 15 2018

Hi,

have a problem with Java stored procedure.

Have a cluster with 2 nodes and 1 file system..

In my case, I need to sign XML document (CLOB) with Java stored procedure so I have implemented a Java stored procedure to sign a String and deployed (compiled it) on Oracle 11g.. What I have noticed is that the same procedure works differently if invoked from node A or node B... For example: If I try to sign an XML document on node A the total time to sign the document is about 30 msec. The same code on node B took about 300 msec. I have tried to drop the Java stored procedure and recreate it (compiled) it on node A and the same on node B but the problem remains the same.

Here is my Java stored procedure:

DROP JAVA SOURCE "DigitalniPodpis";

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "DigitalniPodpis" as import java.security.Key;

import java.security.MessageDigest;

import java.security.PrivateKey;

import java.security.Signature;

import java.util.Enumeration;

import java.io.*;

import java.lang.Integer;

import java.security.*;

import java.util.*;

import javax.xml.crypto.dsig.*;

import javax.xml.crypto.dsig.dom.DOMSignContext;

import javax.xml.crypto.dsig.keyinfo.*;

import javax.xml.crypto.dsig.spec.*;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.transform.*;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.*;

import java.net.URL;

import java.security.KeyManagementException;

import java.security.KeyStore;

import java.security.KeyStoreException;

import java.security.NoSuchAlgorithmException;

import java.security.UnrecoverableKeyException;

import java.security.cert.Certificate;

import java.security.cert.CertificateException;

import java.security.cert.CertificateFactory;

import java.security.cert.X509Certificate;

import javax.net.ssl.HttpsURLConnection;

import javax.net.ssl.KeyManagerFactory;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLSocketFactory;

import javax.net.ssl.TrustManager;

import javax.net.ssl.TrustManagerFactory;

/*********************************************************************************

* Naredil Peter Valencic Izdelava 09.09.2015 Namen metode za generiranje in

* podpisovanje xml datotek za davÄŤno blagajno Datum metoda Spremembe 10.11.2015

* initCert Dodan še trustore, webservice url ter inicializacija HTTPS povezave

*

* //Spodnja verzija je za javo > 1.6.0_25

* //Node node = doc.getElementsByTagName("fu:BusinessPremiseRequest").item(0);

*

* //Spodnja verzija je za javo > 1.6.0_25

*   NodeList nl = doc.getElementsByTagName("fu:BusinessPremiseRequest");

*   Node node = nl.item(0);

*  ((Element) node).setIdAttribute("Id", true);

*

*

* !!!!! PRI PREVAJANJU BODI POZOREN, TRENUNTO JE ZAKOMENTIRAN UKAZ ZA PRIDOBITEV

*  NODE-a pri podpisovanju poslovnega prostora in računa!! odkomentiraj ko prevajaš!!

*

**********************************************************************************/

public class DigitalniPodpis {

    public static String t="";

    public static KeyStore p12 = null;

    public static String geslo;

    public static String vmesni_rezultat = "";

    public static String alias = null;

    public static Key privateKey = null;

    public static Signature podpis = null;

    public static MessageDigest md = null;

    public static StringBuilder sb = new StringBuilder();

    public static HttpsURLConnection httpsURLConnection; //SSL povezava

    public static URL url; //webservice endpoint

    public static StringBuffer response = new StringBuffer();

    public static String inputLine = "";

    //public static DocumentBuilderFactory dbFactory;

    static {

        try {

            podpis = Signature.getInstance("SHA256WithRSA");

            md = MessageDigest.getInstance("MD5");

            //DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();

            //dbFactory.setNamespaceAware(true);

        } catch (Exception ex) {

        }

    }

    public static HttpsURLConnection getHttpsURLConnection(URL url, String truststore, String keystore,

            String keyStorePass, String keyPassword, String KeyStoreType, String KeyManagerAlgorithm, String SSLVersion)

            throws NoSuchAlgorithmException, KeyStoreException,

            CertificateException, FileNotFoundException, IOException,

            UnrecoverableKeyException, KeyManagementException {

        //System.setProperty("javax.net.debug", "ssl,handshake,record");

        SSLContext sslcontext = SSLContext.getInstance(SSLVersion);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerAlgorithm);

        KeyStore ks = KeyStore.getInstance(KeyStoreType);

        ks.load(new FileInputStream(keystore), keyStorePass.toCharArray());

        kmf.init(ks, keyPassword.toCharArray());

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        InputStream is = new FileInputStream(truststore); //"c:/cert/test-tls.cer");

        InputStream caInput = new BufferedInputStream(is);

        Certificate ca;

        try {

            ca = cf.generateCertificate(caInput);

            //System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());

        } finally {

            caInput.close();

        }

        String keyStoreType = KeyStore.getDefaultType();

        KeyStore keyStore = KeyStore.getInstance(keyStoreType);

        keyStore.load(null, null);

        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);

        tmf.init(keyStore);

        TrustManager[] tm = tmf.getTrustManagers();

        sslcontext.init(kmf.getKeyManagers(), tm, null);

        SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory();

        HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);

        HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();

        return httpsURLConnection;

    }

    public static String podpisiRacun(String vhodniXml) throws Exception {

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();

        dbFactory.setNamespaceAware(true);

        Document doc = (Document) dbFactory.newDocumentBuilder().parse(new ByteArrayInputStream(vhodniXml.getBytes()));

        //Spodnja verzija deluje na java <1.6.0_19x

        Node node = doc.getElementsByTagName("fu:InvoiceRequest").item(0);

        //Spodnja verzija je za javo > 1.6.0_25

        //NodeList nl = doc.getElementsByTagName("fu:InvoiceRequest");

        //Node node = nl.item(0);

        //(Element)node.setIdAttribute("Id", true);

        Enumeration e = p12.aliases();

        String alias = (String) e.nextElement();

        //System.out.println("Alias certifikata:" + alias);

        Key privateKey = p12.getKey(alias, geslo.toCharArray());

        KeyStore.PrivateKeyEntry keyEntry

                = (KeyStore.PrivateKeyEntry) p12.getEntry(alias, new KeyStore.PasswordProtection(geslo.toCharArray()));

        X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

        PublicKey publicKey = cert.getPublicKey();

        final XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");

        // Create a Reference to the enveloped document

        Reference ref = sigFactory.newReference("#data",

                sigFactory.newDigestMethod(DigestMethod.SHA256, null),

                Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),

                null,

                null);

        SignedInfo si = sigFactory.newSignedInfo(sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), sigFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null), Collections.singletonList(ref));

        // Create a KeyValue containing the RSA PublicKey

        KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();

        X509IssuerSerial x509IssuerSerial = keyInfoFactory.newX509IssuerSerial(cert.getSubjectX500Principal().getName(), cert.getSerialNumber());

        List x509Content = new ArrayList();

        x509Content.add(cert.getSubjectX500Principal().getName());

        x509Content.add(x509IssuerSerial);

        KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);

        X509Data xd = keyInfoFactory.newX509Data(x509Content);

        // Create a KeyInfo and add the KeyValue to it

        KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(xd));

        // Create a DOMSignContext and specify the RSA PrivateKey and

        // location of the resulting XMLSignature's parent element

        DOMSignContext dsc = new DOMSignContext(

                privateKey,

                node

        );

        // Create the XMLSignature (but don't sign it yet)

        XMLSignature signature = sigFactory.newXMLSignature(si, keyInfo);

        // Marshal, generate (and sign) the enveloped signature

        signature.sign(dsc);

        ByteArrayOutputStream os = new ByteArrayOutputStream();

        Transformer trans = TransformerFactory.newInstance()

                .newTransformer();

        trans.transform(new DOMSource(doc), new StreamResult(os));

        byte[] podatki = os.toByteArray();

        os.close();

        return new String(podatki);

    }

    public static String podpisiPoslovniProstor(String vhodniXml) throws Exception {

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();

        dbFactory.setNamespaceAware(true);

        Document doc = (Document) dbFactory.newDocumentBuilder().parse(new ByteArrayInputStream(vhodniXml.getBytes()));

        //Spodnja verzija je za javo > 1.6.0_25

        Node node = doc.getElementsByTagName("fu:BusinessPremiseRequest").item(0);

        //Spodnja verzija je za javo > 1.6.0_25

        //NodeList nl = doc.getElementsByTagName("fu:BusinessPremiseRequest");

        //Node node = nl.item(0);

        //((Element) node).setIdAttribute("Id", true);

        Enumeration e = p12.aliases();

        String alias = (String) e.nextElement();

        //System.out.println("Alias certifikata:" + alias);

        Key privateKey = p12.getKey(alias, geslo.toCharArray());

        KeyStore.PrivateKeyEntry keyEntry

                = (KeyStore.PrivateKeyEntry) p12.getEntry(alias, new KeyStore.PasswordProtection(geslo.toCharArray()));

        X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

        PublicKey publicKey = cert.getPublicKey();

        final XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");

        // Create a Reference to the enveloped document

        Reference ref = sigFactory.newReference("#data",

                sigFactory.newDigestMethod(DigestMethod.SHA256, null),

                Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),

                null,

                null);

        SignedInfo si = sigFactory.newSignedInfo(sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), sigFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null), Collections.singletonList(ref));

        // Create a KeyValue containing the RSA PublicKey

        KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();

        X509IssuerSerial x509IssuerSerial = keyInfoFactory.newX509IssuerSerial(cert.getSubjectX500Principal().getName(), cert.getSerialNumber());

        List x509Content = new ArrayList();

        x509Content.add(cert.getSubjectX500Principal().getName());

        x509Content.add(x509IssuerSerial);

        KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);

        X509Data xd = keyInfoFactory.newX509Data(x509Content);

        // Create a KeyInfo and add the KeyValue to it

        KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(xd));

        // Create a DOMSignContext and specify the RSA PrivateKey and

        // location of the resulting XMLSignature's parent element

        DOMSignContext dsc = new DOMSignContext(

                privateKey,

                node

        );

        // Create the XMLSignature (but don't sign it yet)

        XMLSignature signature = sigFactory.newXMLSignature(si, keyInfo);

        // Marshal, generate (and sign) the enveloped signature

        signature.sign(dsc);

        ByteArrayOutputStream os = new ByteArrayOutputStream();

        Transformer trans = TransformerFactory.newInstance()

                .newTransformer();

        trans.transform(new DOMSource(doc), new StreamResult(os));

        return new String(os.toByteArray());

    }

    private static String md5Java(byte[] message) throws Exception {

        byte[] hash = md.digest(message); //.getBytes("UTF-8"));

        //StringBuilder sb = new StringBuilder(2 * hash.length);

        sb.setLength(0);

        for (byte b : hash) {

            sb.append(String.format("%02x", b & 0xff));

        }

        return sb.toString();

    }

    /**

     * Metoda inicializira keystore in truststore za SSL povezavo ter podpis

     * dokumentov

     *

     * @param direktorij direktorij kjer se fiziÄŤno nahajajo certifikati

     * @param certifikat naziv datoteke certifikata

     * @param gesloc Geslo certifikata

     * @param trustStoreCertifikat naziv trustStore certifikata

     * @throws Exception

     */

    public static void initCert(String direktorij, String certifikat, String gesloc, String trustStoreCertifikat, String urlWsEndpoint) throws Exception {

        if (certifikat == null) {

            throw new Exception("ime datoteke certifikata za podpis podatkov ni podano!");

        }

        if (gesloc == null) {

            throw new Exception("geslo certifikata ni podano!");

        }

        if (trustStoreCertifikat == null) {

            throw new Exception("ime datoteke certifikata za trustStore ni podano!");

        }

        File f = new File(direktorij+"/"+certifikat);

        if (f.exists() == false)

        {

            throw new Exception("Certifikat za podpis ne obstaja na:" + (direktorij+"/"+certifikat));

        }

        f = new File(direktorij+"/"+trustStoreCertifikat);

        if (f.exists() == false)

        {

            throw new Exception("Certifikat za dostop do https ne obstaja na:" + (direktorij+"/"+trustStoreCertifikat));

        }

        // doloÄŤimo URL do webservisa

        url = new URL(urlWsEndpoint);

        geslo = gesloc;

        if (p12 == null) {

            p12 = KeyStore.getInstance("pkcs12");

            p12.load(new FileInputStream(direktorij + "/" + certifikat), geslo.toCharArray());

            Enumeration e = p12.aliases();

            alias = (String) e.nextElement();

            privateKey = p12.getKey(alias, geslo.toCharArray());

            podpis.initSign((PrivateKey) privateKey);

        }

        //parametri za SSL povezavo

        if (httpsURLConnection == null) {

            SSLContext sslcontext = SSLContext.getInstance("TLSv1.2");

            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

            KeyStore ks = KeyStore.getInstance("PKCS12");

            ks.load(new FileInputStream(direktorij + "/" + certifikat), geslo.toCharArray());

            kmf.init(ks, geslo.toCharArray());

            CertificateFactory cf = CertificateFactory.getInstance("X.509");

            InputStream is = new FileInputStream(direktorij + "/" + trustStoreCertifikat); //"c:/cert/test-tls.cer");

            InputStream caInput = new BufferedInputStream(is);

            Certificate ca;

            try {

                ca = cf.generateCertificate(caInput);

                //System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());

            } finally {

                caInput.close();

            }

            String keyStoreType = KeyStore.getDefaultType();

            KeyStore keyStore = KeyStore.getInstance(keyStoreType);

            keyStore.load(null, null);

            keyStore.setCertificateEntry("ca", ca);

            // Create a TrustManager that trusts the CAs in our KeyStore

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();

            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);

            tmf.init(keyStore);

            TrustManager[] tm = tmf.getTrustManagers();

            sslcontext.init(kmf.getKeyManagers(), tm, null);

            SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory();

            HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);

            //vrnemo https povezavo, ki je globalna in aktivna skozi celo sejo.

            //httpsURLConnection = (HttpsURLConnection) url.openConnection();

        }

    }

        public static String sendXML(String soapAction,String soapEnvelopeXML) throws Exception {

        //nastavimo timeout

        //httpsURLConnection.setConnectTimeout(Integer.valueOf(timeoutMsec).intValue());

        if (httpsURLConnection == null) {

            httpsURLConnection = (HttpsURLConnection) url.openConnection();

        }

        //nastavimo header-je

        httpsURLConnection.setRequestMethod("POST");

        httpsURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");

        httpsURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        httpsURLConnection.setRequestProperty("Content-type", "text/xml; charset=utf-8");

        httpsURLConnection.setRequestProperty("SOAPAction", soapAction);

        httpsURLConnection.setDoOutput(true);

            OutputStream reqStream = httpsURLConnection.getOutputStream();

            reqStream.write(soapEnvelopeXML.getBytes());

            int responseCode = httpsURLConnection.getResponseCode();

            //System.out.println("\nSending 'POST' request to URL : " + url);

            //System.out.println("Response Code : " + responseCode);

            if (responseCode == 200) {

                BufferedReader in = new BufferedReader(

                        new InputStreamReader(httpsURLConnection.getInputStream()));

                String inputLine;

               // StringBuffer response = new StringBuffer();

                response.setLength(0);

                while ((inputLine = in.readLine()) != null) {

                    response.append(inputLine);

                }

                in.close();

                httpsURLConnection.disconnect();

                return response.toString();

            }

            else

            {

                httpsURLConnection.disconnect();

                throw new Exception("Napaka pri povezavi na streĹľnik "+ url + ". Koda napake: " + responseCode);

            }

    }

     public static String sendXMLT(int timeout,String soapAction,String soapEnvelopeXML) throws Exception {

        httpsURLConnection = (HttpsURLConnection) url.openConnection();

        //nastavimo timeout

        httpsURLConnection.setConnectTimeout(timeout);

        httpsURLConnection.setReadTimeout(timeout);

      //nastavimo header-je

        httpsURLConnection.setRequestMethod("POST");

        httpsURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");

        httpsURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        httpsURLConnection.setRequestProperty("Content-type", "text/xml; charset=utf-8");

        httpsURLConnection.setRequestProperty("SOAPAction", soapAction);

        httpsURLConnection.setDoOutput(true);

            OutputStream reqStream = httpsURLConnection.getOutputStream();

            reqStream.write(soapEnvelopeXML.getBytes());

            int responseCode = httpsURLConnection.getResponseCode();

            //System.out.println("\nSending 'POST' request to URL : " + url);

            //System.out.println("Response Code : " + responseCode);

            if (responseCode == 200) {

                BufferedReader in = new BufferedReader(

                        new InputStreamReader(httpsURLConnection.getInputStream()));

                response.setLength(0);

                while ((inputLine = in.readLine()) != null) {

                    response.append(inputLine);

                }

                in.close();

                httpsURLConnection.disconnect();

                return response.toString();

            }

            else

            {

                httpsURLConnection.disconnect();

                throw new Exception("Napaka pri povezavi na streĹľnik "+ url + ". Koda napake: " + responseCode);

            }

    }

    public static String getZOI(

            String davcnaStevilka,

            String datumIzdaje,

            String stevilkaRacuna,

            String oznakaPoslovnegaProstora,

            String electronicDeviceId,

            String znesekRacuna) throws Exception {

        //sestavimo vrstico

        vmesni_rezultat = davcnaStevilka.concat(datumIzdaje).concat(stevilkaRacuna).concat(oznakaPoslovnegaProstora).concat(electronicDeviceId).concat(znesekRacuna);

        podpis.update(vmesni_rezultat.getBytes("UTF-8"));

        byte[] podpisano = podpis.sign();

        //MD5 hash

        return md5Java(podpisano);

    }

}

/

Is something that I'm missing?  Why the same code works differently if invoked on node A or B?

Do you think If I try to "load" only the class file with loadjava will resolve this problem?

thank you

Peter

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 12 2018
Added on Jun 1 2018
3 comments
1,070 views