2 Replies Latest reply: Sep 12, 2013 8:44 AM by Mike Kutz RSS

    call java from apex

    Ahmed Alsaied

      i have java class to call scanner device and jar file , i want to call this method in oracle apex

      when the end user press on the button on apex scanner scan image and insert it in the database as a blob file .

      find attach the class and jar file that java developer created for me

      http://www.mediafire.com/?a14ml4688b62nmu

      , but i don't know how to use it in oracle apex .

      i use java applet that the following code:

       

      <applet code=ScannerUtility.class

              archive="/i/JTwain.jar"

              width="120" height="120">

      </applet>

       

       

      but not working ,  in apex i try another solution to call java in database like this example

      http://kristianjones.blogspot.com/2007/05/call-java-methods-from-apex-for-those.html

       

      i create the following code ;

       

      CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "ScannerUtility"

      AS

      import java.awt.Image;

      import java.awt.image.BufferedImage;

      import java.io.File;

      import java.io.FileInputStream;

      import java.io.FileOutputStream;

      import java.io.InputStream;

      import java.sql.Connection;

      import java.sql.DriverManager;

      import java.sql.PreparedStatement;

      import java.text.SimpleDateFormat;

      import java.util.ArrayList;

      import java.util.Calendar;

      import java.util.List;

      import com.asprise.util.jtwain.Source;

      import com.asprise.util.jtwain.SourceManager;

      import com.itextpdf.text.Document;

      import com.itextpdf.text.pdf.PdfWriter;

      public class ScannerUtility {

      private String scannerName;

      private List<Image> images;

      private File generatedTempFile=null;

       

      public ScannerUtility()

      {

      }

       

      public ScannerUtility(String scannerName)

      {

      this.scannerName=scannerName;

      }

       

      public File getGeneratedFile()

      {

      return generatedTempFile;

      }

       

      private void setGeneratedFile(File file)

      {

      generatedTempFile=file;

      }

       

      synchronized void doScan()

      {

      try {

      if(!scannerName.equals(""))

      {

                  Source source = SourceManager.instance().selectSourceByName(scannerName);

                  if(source == null) {

                      return;

                  }

          source.open();

          images = new ArrayList<Image>();

       

          do {

      BufferedImage image = source.acquireImageAsBufferedImage();

        images.add(image);

      } while (source.hasMoreImages());

       

          source.close();

          setGeneratedFile(generatePDF(images));

      }

      }catch(Exception e) {

          e.printStackTrace();

      }finally{

          SourceManager.closeSourceManager();

      }

      }

       

      public void scanFiles()

      {

      doScan();

      }

       

      private File generatePDF(java.util.List<java.awt.Image> images)

      {

      File temp=null;

      try {

      Document document = new Document();

      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());

      temp = File.createTempFile("Scanned_"+ timeStamp , ".pdf");

          PdfWriter.getInstance(document,new FileOutputStream(temp));

       

      document.open();

      for (java.awt.Image img : images) {

      com.itextpdf.text.Image  image = com.itextpdf.text.Image.getInstance(img,null);

      document.add(image);

      }

       

      document.close();

      } catch (Exception e) {

      e.printStackTrace();

      }

      return temp;

      }

       

      public void saveGeneratedFile()

      {

      String serverName="192.168.0.100";

      String portNumber="1522";

      String sid="xe";

      String username="test";

      String password="1";

      String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber + ":" + sid;

      try{

      Class.forName("oracle.jdbc.driver.OracleDriver");

      Connection conn = DriverManager.getConnection(url, username, password);

              PreparedStatement ps = conn.prepareStatement("INSERT INTO Scanner_file (FILESIZE,MIMETYPE,CONTENT,FILENAME) VALUES (?,?,?,?)");

                    InputStream bodyIn =  new FileInputStream(getGeneratedFile().getAbsolutePath());

                    File fileIn = new File(getGeneratedFile().getAbsolutePath());

                    ps.setString(1, String.valueOf((int)fileIn.length()));

                    ps.setString(2, getExtension(fileIn));

                        ps.setBinaryStream(3, bodyIn, (int)fileIn.length());

                        ps.setString(4, fileIn.getName());

                        int count = ps.executeUpdate();

                        bodyIn.close();

                        ps.close();

                    conn.close();

                    getGeneratedFile().deleteOnExit();

      }

      catch(Exception ex)

      {

      ex.printStackTrace();

      }

      }

       

      public void ignoreSaveGeneratedFile()

      {

      getGeneratedFile().deleteOnExit();

      getGeneratedFile().delete();

      }

       

       

      private String getExtension(File f) {

          String ext = null;

          String s = f.getName();

          int i = s.lastIndexOf('.');

          if (i > 0 ){ if ( i < s.length() - 1) {

              ext = s.substring(i+1).toLowerCase();

          }}

          return ext;

      }

      public void scan_delete()

      {

          scanFiles();

      ignoreSaveGeneratedFile();

      }

      public void scan_save()

      {

          scanFiles();

      saveGeneratedFile()();

      }

      };

      /
      
      

       

       

      and then i created two procedure

       

       

      create or replace PROCEDURE scan_save

      AUTHID CURRENT_USER AS LANGUAGE

      JAVA NAME  'ScannerUtility.scan_save()';

       

       

       

      create or replace PROCEDURE scan_delete

      AUTHID CURRENT_USER AS LANGUAGE

      JAVA NAME  'ScannerUtility.scan_delete()';

       

       

      in apex i create tow buttons depend in process to execute procedures:

       

      process pl/sql

      source :

      scan_save();

       

      another one execute the another procedure

      scan_delete();

       

      put i have error when i pressed in buttons

      • ORA-29541: class AMER.ScannerUtility could not be resolved
        • 1. Re: call java from apex
          Jonathan Taylor

          One thing that looks wrong is that scan_save() and scan_delete in your Java source needs to be defined as static.

           

          E.g.

          public static void scan_delete()

          {

               scanFiles();

            ignoreSaveGeneratedFile();

          }

          public static void scan_save()

          {

               scanFiles();

            saveGeneratedFile()();

          }

          • 2. Re: call java from apex
            Mike Kutz

            How is the scanner being accessed through Java?

            USB? RS232? parallel? SCSI? special TCP? web service?

            Most likely it will be using TWAIN protocol.

             

            My biggest concern is Java's security model.

            If you can make the <applet> code work when the HTML page and all Jar/class files are on a remote server, then you can make it work in APEX.

            In order to do that, you will need to create an Item Type plugin.

             

            General Tips for Java <applet> code in APEX

            The Java Class needs to have appropriate getData() and setData() functions.

            The plugin will produce the <applet> code AND a hidden <input> HTML element.

            The ID of the hidden <input> should have the name of the APEX Item

            And the <applet> should have the ID of the APEX Item but with a suffix (eg _APP) to keep it unique within the HTML page.

            Dynamic Actions are used to call the getData() and setData() routines.

            These call JavaScript that will transfer data between the Java Applet and the hidden <input> item.

            A single JavaScript file that holds most of the code will help ease programming.

            If you can, make the Dynamic Actions as plugins also.

            All of the JAR files and javascript files should be part of the Item Type Plugin.

            Once all of this is done, you access the values (ie the data of the java applet) as if it were any other APEX Item.

             

            I've made 3 different item types like this already.

            The big problem comes in when your data is >32k in size.

            You'll have to add a lot of extra work to transfer that amount of data to/from the server.

            (The Enkitec Load CLOB works very well for this.)

             

            MK