Forum Stats

  • 3,872,603 Users
  • 2,266,457 Discussions
  • 7,911,262 Comments

Discussions

What's the best way for persistence in a Desktop stand alone application?

wellington7
wellington7 Member Posts: 157
edited Feb 12, 2010 6:52AM in Java Desktop Applications
I was thinking about hibernate, but I think it is so slow (to boot) for a simple desktop application.
In the Serialization javadoc they recommend us to use the XMLEncoder, but I don't want the user to have a so easy access to the data (as user password) in a xml file.

So, what do say?

Comments

  • wellington7
    wellington7 Member Posts: 157
    All I have till now is the [Using the Java Persistence API in Desktop Applications|http://java.sun.com/developer/technicalArticles/J2SE/Desktop/persistenceapi/] page, from June 2007, and the [same question|http://stackoverflow.com/questions/37271/whats-the-best-way-to-persist-data-in-a-java-desktop-application] from September 2008.
    If nothing change, it looks like hibernate is a good approach.. but I still think it is a too slow system for a simple desktop app.
  • wellington7
    wellington7 Member Posts: 157
    edited Feb 3, 2010 12:32PM
    Thinking...
    The problem of doing persistence by hand, going into each object and writing on file each attribute, is to debug it later (I did this in a old little project).
  • wellington7
    wellington7 Member Posts: 157
    To whom it may concern, my conclusion from today's research and tests is that the best is do it by hand. It's easier debug myself code then someone else's powerful-easy-fast framework.
  • 843810
    843810 Member Posts: 46,938
    I use XMLEncoder/Decode in combination with CipherOutputStream/InputStream to encrypt data

    here's a code snippet
    public class FileUtils {
    
        static byte[] salt = {
            (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
            (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
        };
        // Iteration count
        static int iterationCount = 19;
        static String passPhrase = java.util.ResourceBundle.getBundle(AdminToolConstants.CONFIGURATION_RB).getString("key");
        private static Cipher c;
        private static void init(int mode) throws InvalidKeySpecException, NoSuchAlgorithmException, ClassNotFoundException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException
        {
        KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
        Class spec = Class.forName("javax.crypto.spec.DESKeySpec");
        c = Cipher.getInstance(key.getAlgorithm());
        c.init(mode, key, paramSpec);
        }
        
          /*
         * writes AdminData object  to  xml file 
         */
        public static void writeToAdminFile(AdminData pAdminData) {
            try {
    
                init(Cipher.ENCRYPT_MODE);
                XMLEncoder e = new XMLEncoder(new CipherOutputStream(
                        new BufferedOutputStream(
                        new FileOutputStream(java.util.ResourceBundle.getBundle(AdminToolConstants.CONFIGURATION_RB).getString("adminfile"))), c));
                e.writeObject(pAdminData);
                e.close();
            } catch (Exception ex) {
                LogFile.logErr("FileUtils", "writeToAdminFile", ex.toString(), ex.getMessage());
                JOptionPane.showMessageDialog(AdminTool.getInstance(), java.util.ResourceBundle.getBundle(AdminToolConstants.ADMIN_TOOL_RB).getString("errror.in.writing.admin.information"));
            }
    
        //Decodes the xml file in to AdminData object
        public static AdminData getAdminData(String pAdminfilename) {
            AdminData mAdminData = null;
            try {
    
                File mAdminFile = new File(pAdminfilename);
                          init(Cipher.DECRYPT_MODE);
                XMLDecoder lXMLDecoder = new XMLDecoder(new CipherInputStream(
                        new BufferedInputStream(new FileInputStream(java.util.ResourceBundle.getBundle(AdminToolConstants.CONFIGURATION_RB).getString("adminfile"))), c));
                Object result = lXMLDecoder.readObject();
    
                mAdminData = (AdminData) result;
                lXMLDecoder.close();
            } catch (Exception ex) {
                LogFile.logErr("FileUtils", "GetAdminData", ex.toString(), ex.getMessage());
                JOptionPane.showMessageDialog(null, ex);
                System.exit(1);
            }
            return mAdminData;
        }
    
     
        }
  • wellington7
    wellington7 Member Posts: 157
    Since you gave the example, could you made it a runnable example? I cannot run because of some missing classes like AdminToolConstants.

    Thanks!
  • 843810
    843810 Member Posts: 46,938
    Try something like this.
    instead of Object yourobject you can use the object you want to save, e.g. if you have a class ConfigData
    use ConfigData data instead of Object yourobject
    public class FileUtils {
     
        static byte[] salt = {
            (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
            (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
        };
        // Iteration count
        static int iterationCount = 19;
        static String passPhrase = "your secret key";
        private static Cipher c;
        private static void init(int mode) throws InvalidKeySpecException, NoSuchAlgorithmException, ClassNotFoundException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException
        {
        KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
        Class spec = Class.forName("javax.crypto.spec.DESKeySpec");
        c = Cipher.getInstance(key.getAlgorithm());
        c.init(mode, key, paramSpec);
        }
        
          /*
         * writes  object  to  xml file 
         */
        public static void write(Object yourobject,String filename) {
            try {
     
                init(Cipher.ENCRYPT_MODE);
                XMLEncoder e = new XMLEncoder(new CipherOutputStream(
                        new BufferedOutputStream(
                        new FileOutputStream(filename)), c));
                e.writeObject(yourobject);
                e.close();
            } catch (Exception ex) {
               ex.printStackTrace() ;       }
     
        //Decodes the xml file 
        public static Object read(String filename){
            Object yourobject = null;
            try {
              
                          init(Cipher.DECRYPT_MODE);
                XMLDecoder lXMLDecoder = new XMLDecoder(new CipherInputStream(
                        new BufferedInputStream(filename), c));
              yourobject = lXMLDecoder.readObject();      
                lXMLDecoder.close();
            } catch (Exception ex) {
                 ex.printStackTrace();
            }
            return yourobject;
        }
         }
  • wellington7
    wellington7 Member Posts: 157
    Thanks, I appreciate your help, and I will read more about javax.crypto.
    By the way, your code still isn't running, maybe you could make a SSCCE.
    Anyway, thanks again!
  • wellington7
    wellington7 Member Posts: 157
    The working code (still not a sscce, missing a working main()):
    /**
     * Example xmlEncoder with cryptography from:
     * 
     * Java Desktop Applications - What's the best way for persistence in a Desktop
     * stand alone application?
     * 
     * http://forums.sun.com/thread.jspa?threadID=5426644
     * 
     */
    
    public class FileUtils {
    
        static byte[] salt = { (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32, (byte) 0x56, (byte) 0x35,
    	    (byte) 0xE3, (byte) 0x03 };
        // Iteration count
        static int iterationCount = 19;
        static String passPhrase = "your secret key";
        private static Cipher c;
    
        private static void init(int mode) throws InvalidKeySpecException, NoSuchAlgorithmException,
    	    ClassNotFoundException, NoSuchPaddingException, InvalidKeyException,
    	    InvalidAlgorithmParameterException {
    	KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
    	SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
    	AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
    	Class spec = Class.forName("javax.crypto.spec.DESKeySpec");
    	c = Cipher.getInstance(key.getAlgorithm());
    	c.init(mode, key, paramSpec);
        }
    
        /*
         * writes object to xml file
         */
        public static void write(Object yourobject, String filename) {
    	try {
    
    	    init(Cipher.ENCRYPT_MODE);
    	    XMLEncoder e = new XMLEncoder(new CipherOutputStream(new BufferedOutputStream(
    		    new FileOutputStream(filename)), c));
    	    e.writeObject(yourobject);
    	    e.close();
    	} catch (Exception ex) {
    	    ex.printStackTrace();
    	}
        }
    
        // Decodes the xml file
        public static Object read(String filename) {
    	Object yourobject = null;
    	try {
    
    	    init(Cipher.DECRYPT_MODE);
    	    XMLDecoder lXMLDecoder = new XMLDecoder(new CipherInputStream(new BufferedInputStream(
    		    new FileInputStream(filename)), c));
    	    yourobject = lXMLDecoder.readObject();
    	    lXMLDecoder.close();
    	} catch (Exception ex) {
    	    ex.printStackTrace();
    	}
    	return yourobject;
        }
        
    }
This discussion has been closed.