<<TableOfContents(2)>>

= Java =

Programming language, platform and process level virtualization . 

== System Properties ==

https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
https://docs.oracle.com/javame/config/cdc/cdc-opt-impl/ojmeec/1.0/runtime/html/localization.htm

||'''Key'''||'''Meaning'''||
||file.separator||Character that separates components of a file path. This is "/" on UNIX and "\" on Windows.||
||java.class.path||Path used to find directories and JAR archives containing class files. Elements of the class path are separated by a platform-specific character specified in the path.separator property.||
||java.home||Installation directory for Java Runtime Environment (JRE)||
||java.vendor||JRE vendor name||
||java.vendor.url||JRE vendor URL||
||java.version||JRE version number||
||line.separator||Sequence used by operating system to separate lines in text files||
||os.arch||Operating system architecture||
||os.name||Operating system name||
||os.version||Operating system version||
||path.separator||Path separator character used in java.class.path||
||user.dir||User working directory||
||user.home||User home directory||
||user.name||User account name||
||user.language|| Two-letter language name code based on ISO 639||
||user.region|| Two-letter region name code based on ISO 3166||
||file.encoding|| Default character-encoding name based on the IANA Charset MIB||

== Regular expressions ==
{{{#!Java
/*
javac TesteRe.java 
java -cp . TesteRe 
*/
/*
gcj -C TesteRe.java  # compile with gcj, GNU compiler for Java
gij -cp . TesteRe # run with gij, GNU interpreter for Java

Linux executable
gcj --main=TesteRe -g -o TesteRe TesteRe.java
ldd TesteRe
./TesteRe
*/

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class TesteRe{

    public static void main(String args[]){ 
        String values[]={"aa12.txt","a123sss.txt","bs11bb.txt","123aaaa.sql","a12.txt","aaaa12","20ghj","6657"};
        Pattern a = Pattern.compile("^(\\D+)(\\d+)(\\D+)$");
        Pattern b = Pattern.compile("^(\\d+)(\\D+)$");
        Pattern c = Pattern.compile("^(\\D+)(\\d+)$");
        Pattern d = Pattern.compile("^(\\d+)$");

        for(String item:values){
            Matcher ma = a.matcher(item);
            Matcher mb = b.matcher(item);
            Matcher mc = c.matcher(item);
            Matcher md = d.matcher(item);

           if(ma.matches()){ 
               int val = Integer.parseInt(ma.group(2)) + 1;
               System.out.println(String.format("A: mv %s %s%d%s",item,ma.group(1),val,ma.group(3)  ) );
           }

           if(mb.matches()){ 
               int val = Integer.parseInt(mb.group(1)) + 1;
               System.out.println(String.format("B: mv %s %d%s",item, val , mb.group(2)  ) );
           }

           if(mc.matches()){ 
               int val = Integer.parseInt(mc.group(2)) + 1;
               System.out.println(String.format("C: mv %s %s%d",item,mc.group(1),val   ) );
           }

           if(md.matches()){ 
               int val = Integer.parseInt(md.group(1)) + 1;
               System.out.println(String.format("D: mv %s %d",item, val  ) );
           }

        }
    }
}

}}}

== Server/client ==
Server
{{{#!java
import java.net.ServerSocket;
import java.net.Socket;
import java.lang.Thread;
import java.util.Stack;

public class SocketServer{
    public static void main(String []args){
        ServerSocket ss = null; 
        int nrThreads= Runtime.getRuntime().availableProcessors() * 2; 
        System.out.println("Nr cores:" + nrThreads);
        ConnHandler[] c = new ConnHandler[nrThreads];
        for(int i=0;i<nrThreads;i++){
            c[i]=new ConnHandler();
            c[i].start();
        }
        
        try{ 
            ss = new ServerSocket(1234); 
            ss.setReuseAddress(true);
        }
        catch(Exception ex){    }
        long count=0;
        while(true){
          try{
            Socket s = ss.accept(); 
            s.setSoLinger(true,0);
            int idx = (int)count%nrThreads;
            c[ idx  ].addSocket(s);
            count++;
            
          }
          catch(Exception ex){
              System.out.println(ex.getMessage());
          }
        }
    }
}
}}}

ConnHandler
{{{#!java
import java.net.ServerSocket;
import java.net.Socket;
import java.lang.Thread;
import java.util.Stack;

public class ConnHandler extends Thread{
    private byte[] rx;
    private Stack stack;
    long tid;

    public ConnHandler(){
        this.rx= new byte[1024];
        this.stack = new Stack();
    }

    public void addSocket(Socket s){
        this.stack.push(s);
    }

    public void run(){
        this.tid = Thread.currentThread().getId();

        while(true){
            if( this.stack.empty() == false){
                Socket s = (Socket)this.stack.pop();
                try{
                    if( s.getInputStream().available() > 0 ){
                        int readedBytes = s.getInputStream().read( rx );
                         System.out.println("ThreadId:"+tid  + " ReadedBytes:"+ readedBytes + 
" StackSize:" + this.stack.size() );
                    }
                    s.close();
                }
                catch(Exception ex){
                } 
            }
            else{ try{ Thread.sleep(500); }catch(Exception ex){} }
        }
    }
}
}}}

Client (python)
{{{#!python
import threading
import time
import socket

class Client (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self) #required

    def run(self):
        for x in range(1,100):
            HOST = 'localhost'
            PORT = 1234
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            print('connecting...')
            s.connect((HOST, PORT))
            print('sending config...')
            s.send('test\r\n')
            s.close()
            print('complete')

if __name__=='__main__':
    clients=[]
    for x in range(1,100):
        clients.append( Client() )
    for c in clients:
        c.start()
}}}


== JAVA_TOOL_OPTIONS ==
Since the command-line cannot always be accessed or modified, for example in embedded VMs or simply VMs launched deep within scripts, a JAVA_TOOL_OPTIONS variable is provided so that agents may be launched in these cases.
{{{#!highlight sh
set JAVA_TOOL_OPTIONS=-Dfile.encoding=utf8
export JAVA_TOOL_OPTIONS=-Dfile.encoding=utf8
}}}

http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#tooloptions

== Access private field via reflection ==
 * http://stackoverflow.com/questions/1555658/is-it-possible-in-java-to-access-private-fields-via-reflection
{{{#!highlight java
java.lang.reflect.Method  m[] = ClassX.class.getDeclaredMethods();
// Object invoke(Object obj, Object... args)
// Invokes the underlying method represented by this Method object, on the specified object with the specified parameters.
java.lang.reflect.Field f = ClassX.class.getDeclaredField("fieldx");
f.setAccessible(true);
//  get(Object obj)
// Returns the value of the field represented by this 
// Field, on the specified object.
f.get(objClassx);
// set(Object obj, Object value)
// Sets the field represented by this Field object 
// on the specified object argument to the specified new value.
f.set(objClassx, fieldValue);
FieldType ft = f.get(objectWithPrivateField);
}}}

== Generate Javadoc using command line ==
{{{#!highlight sh
dir /s /b *.java > javafiles.txt
javadoc -encoding UTF-8 -d docs @javafiles.txt
}}}
To add an overview file add -overview overview.html

== Java keystore public private keys ==
{{{#!highlight sh
keytool -genkey -alias test1rsa -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore1.p12 -validity 3650
#Enter keystore password:  
#Re-enter new password: 
#What is your first and last name?
#  [Unknown]:  
#What is the name of your organizational unit?
#  [Unknown]:  
#What is the name of your organization?
#  [Unknown]:  
#What is the name of your City or Locality?
#  [Unknown]:  
#What is the name of your State or Province?
#  [Unknown]:  
#What is the two-letter country code for this unit?
#  [Unknown]:  
#Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
#  [no]:  yes
keytool -list -v -keystore keystore1.p12 -storetype pkcs12  
}}}

{{{#!highlight java
/*
javac keypair.java
java -classpath . keypair
*/
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Key;
import java.security.cert.Certificate;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.EncodedKeySpec;
import java.io.FileInputStream;
import java.security.KeyFactory;

public class keypair{
    public static final String X509 = "X.509";
    public static final String RSA = "RSA";
    public static final String PKCS8 = "PKCS#8"; 
    public static final String PKCS12 = "PKCS12";
    
    private static Key loadKey(String filename,String format,String algorithm){
        Key ret=null;
        
        try{
            FileInputStream keyfis = new FileInputStream( filename );
            byte[] data = new byte[keyfis.available()];
            keyfis.read(data);
            keyfis.close();
            
            EncodedKeySpec spec = null;
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            if(PKCS8.equals(format)){
                spec = new PKCS8EncodedKeySpec(data);
                ret = keyFactory.generatePrivate(spec);
                System.out.println(String.format("Loading %s in format %s",filename , ret.getFormat() ) );
            }
            
            if(X509.equals(format)){
                spec = new X509EncodedKeySpec(data);
                ret = keyFactory.generatePublic(spec);
                System.out.println(String.format("Loading %s in format %s",filename , ret.getFormat() ) );
            }            
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        
        return ret;
    }   
    
    private static void saveKey(Key key,String filename){
        try{
            System.out.println(String.format("Saving %s in format %s",filename , key.getFormat() ) );
            byte[] encodedKey = key.getEncoded();
            FileOutputStream keyfos = new FileOutputStream( filename );
            keyfos.write(encodedKey);
            keyfos.close();            
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }
    
    private static byte[] encrypt(Key key,String payload){
        byte[] res=null;
        try{        
            Cipher cipher = Cipher.getInstance(key.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, key);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            CipherOutputStream cos = new CipherOutputStream(baos, cipher);
            byte[] b = payload.getBytes();
            System.out.println( b.length );
            cos.write(b);
            cos.flush();
            cos.close();            
            res = baos.toByteArray();
            
            System.out.println("Res size: "+ res.length );            
            for(int i=0;i<res.length;i++){
                System.out.print(String.format("%02X",res[i]));
            }
            
            System.out.println();            
        }
        catch(Exception ex){
            ex.printStackTrace();
        }   
        return res;
    }
    
    private static void decrypt(Key key,byte[] res){
        try{        
            Cipher cipherDec = Cipher.getInstance(key.getAlgorithm());
            cipherDec.init(Cipher.DECRYPT_MODE, key);
            ByteArrayOutputStream baosdec = new ByteArrayOutputStream();
            CipherOutputStream cosdec = new CipherOutputStream(baosdec, cipherDec);
            System.out.println( res.length );
            cosdec.write(res);
            cosdec.flush();
            cosdec.close();            
            byte[] resDec = baosdec.toByteArray();        
            
            System.out.println("Res size: "+ resDec.length );            
            for(int i=0;i<resDec.length;i++){
                System.out.print(String.format("%s",(char)resDec[i]));
            }
            
            System.out.println();
            
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }
    
    public static void main(String args[]){
        KeyStore ks = null;
        java.io.FileInputStream fis = null;
        String pass = "12345678";
        String alias = "test1rsa";
        
        try {
            ks = KeyStore.getInstance(PKCS12);
            fis = new java.io.FileInputStream("keystore1.p12");
            ks.load(fis, pass.toCharArray());
            fis.close();
            KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(pass.toCharArray());         
            KeyStore.Entry pkEntry = ks.getEntry(alias, protParam);
            KeyStore.PrivateKeyEntry prvKeyEntry = ((KeyStore.PrivateKeyEntry)pkEntry);
            PrivateKey privateKey = prvKeyEntry.getPrivateKey();
            Certificate myCert = ks.getCertificate(alias);
            //Certificate myCert =prvKeyEntry.getCertificate();
            PublicKey publicKey = myCert.getPublicKey();
            
            System.out.println("PrivKeyAlg:" + privateKey.getAlgorithm() );
            System.out.println("PubKeyAlg:" + publicKey.getAlgorithm() );
            //------------------

            byte[] res = encrypt(privateKey,"secret");
            decrypt(publicKey,res);            
            
            byte[] resOther = encrypt(publicKey,"otherSecret");
            decrypt(privateKey,resOther);            
            saveKey(publicKey,"publicKey.bin");
            saveKey(privateKey,"privateKey.bin");
            
            loadKey("publicKey.bin", X509,RSA);
            loadKey("privateKey.bin",PKCS8,RSA);
            loadKey("privateKey.bin",PKCS8,RSA);
        } 
        catch(Exception ex){            
            ex.printStackTrace();
        }        
    }
}
}}}

== GCJ example desktop app ==
{{{#!highlight sh
javac ToolbarFrame1.java BasicWindowMonitor.java # compile
java ToolbarFrame1 # run
}}}

=== ToolbarFrame1.java ===
{{{#!highlight java
/*
gcj --main=ToolbarFrame1 -g -o ToolbarFrame1 ToolbarFrame1.java BasicWindowMonitor.java
 */
import java.awt.*;
import java.awt.event.*;

public class ToolbarFrame1 extends Frame implements ActionListener {
  Button cutButton, copyButton, pasteButton;
  
  public ToolbarFrame1() {
    super("Toolbar Example (AWT)");
    setSize(450, 250);
    //addWindowListener(new BasicWindowMonitor());
    WindowListener wl = new WindowListener(){
        public void windowActivated(WindowEvent e){   
            System.out.println("Activated");
        }

        public void windowClosed(WindowEvent e){
            System.out.println("Closed");
            System.exit(0);      
        }

        public void windowClosing(WindowEvent e){   
            Window w = e.getWindow();
            w.setVisible(false);
            w.dispose();    
            System.out.println("Closing");
        }

        public void windowDeactivated(WindowEvent e){   
            System.out.println("Deactivated");
        }

        public void windowDeiconified(WindowEvent e){   
            System.out.println("Deiconified");
        }

        public void windowIconified(WindowEvent e){   
            System.out.println("Iconified");
        }

        public void windowOpened(WindowEvent e){   
            System.out.println("Opened");
        }
        
    }; 
    addWindowListener( wl );
  
    Panel toolbar = new Panel();
    toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));

    cutButton = new Button("Cut");
    cutButton.addActionListener(this);
    toolbar.add(cutButton);

    copyButton = new Button("Copy");
    copyButton.addActionListener(this);
    toolbar.add(copyButton);

    pasteButton = new Button("Paste");
    pasteButton.addActionListener(this);
    toolbar.add(pasteButton);

    add(toolbar, BorderLayout.NORTH);
  }

  public void actionPerformed(ActionEvent ae) {
    System.out.println(ae.getActionCommand());
  }

  public static void main(String args[]) {
    ToolbarFrame1 tf1 = new ToolbarFrame1();
    tf1.setVisible(true);
  }
  
}
}}}

=== BasicWindowMonitor.java ===
{{{#!highlight java
import java.awt.event.*;
import java.awt.Window;

public class BasicWindowMonitor extends WindowAdapter {

  public void windowClosing(WindowEvent e) {
    Window w = e.getWindow();
    w.setVisible(false);
    w.dispose();
    System.exit(0);
  }
}
}}}

== Install Oracle jdk8 in Slackware64 15.0 ==
 * Get from http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html Linux64 tar gz
{{{#!highlight bash
mkdir -p /opt/java
cp jdk-8u162-linux-x64.tar.gz /opt/java/
cd /opt/java/
tar xvzf jdk-8u162-linux-x64.tar.gz 
cd jdk1.8.0_162/bin
./java
}}}

{{{#!highlight bash
cd ~/Downloads/
wget https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_linux-x64_bin.tar.gz 
tar xvzf openjdk-17.0.2_linux-x64_bin.tar.gz 
mv jdk-17.0.2/ ~/
cd ~/jdk-17.0.2/bin/
./java -version
nano ~/.bashrc 
# PATH=$PATH:~/jdk-17.0.2/bin
source .bashrc 
java -version
}}}

=== Add to .bashrc ===
 * ~/.bashrc
{{{#!highlight bash
PATH=$PATH:/opt/java/jdk1.8.0_162/bin
}}}

== Float error ==
{{{
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
What Every Computer Scientist Should Know About Floating-Point Arithmetic
IEEE 754
The IEEE standard defines four different precisions: single, double, single-extended, and double-extended.
Since rounding error is inherent in floating-point computation, it is important to have a way to measure this error. 

}}}

== Generics ==
 * https://docs.oracle.com/javase/tutorial/java/generics/why.html
Generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods.

Advantages:
 * Stronger type checks at compile time
 * Elimination of casts
 * Enabling programmers to implement generic algorithms

== Swing test ==

{{{#!highlight java
/*
javac SwingTest.java
java SwingTest 
*/
import javax.swing.*;
import java.awt.event.*;

public class SwingTest {
    private static void createFrame() {
        JFrame frame = new JFrame("JFrameTitle");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);

	JTextField jtf = new JTextField();
	jtf.setBounds(5,80,100,25);

        JLabel label = new JLabel("JLabel");
        label.setBounds(5,5,100,25); 
	JButton button = new JButton("Press me");
        button.setBounds(5,35,100,25);
        ActionListener al = new ActionListener(){
            public void actionPerformed(ActionEvent e){
		System.out.println("Pressed " + jtf.getText() );
	    }
        };
        button.addActionListener( al );

        frame.getContentPane().add(label);
        frame.getContentPane().add(button);
        frame.getContentPane().add(jtf);
        frame.pack();
        frame.setVisible(true);
        frame.setSize(640,480);
    }

    public static void main(String[] args) {
        createFrame();
    }
}
}}}


== XML signature example ==
 * https://docs.oracle.com/javase/8/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html
{{{
.
├── dummy.xml
├── pom.xml
├── signed.xml
├── src
│   └── main
│       └── java
│           └── org
│               └── allowed
│                   └── bitarus
│                       └── xmlsign
│                           ├── KeyValueKeySelector.java
│                           ├── Main.java
│                           └── SimpleKeySelectorResult.java
}}}


=== pom.xml ===
{{{#!highlight xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
        http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.allowed.bitarus</groupId>
        <artifactId>xmlsign</artifactId>
        <packaging>jar</packaging>
        <version>0.0.1</version>
        <name>xmlsign</name>
        <url>http://maven.apache.org</url>
        <build>
                <plugins>
                        <plugin>
                                <artifactId>maven-assembly-plugin</artifactId>
                                <version>2.4</version>
                                <configuration>
                                        <descriptorRefs>
                                                <descriptorRef>jar-with-dependencies</descriptorRef>
                                        </descriptorRefs>
                                        <archive>
                                                <manifest>
                                                        <mainClass>org.allowed.bitarus.xmlsign.Main</mainClass>
                                                </manifest>
                                        </archive>
                                </configuration>
                                <executions>
                                        <execution>
                                                <id>make-assembly</id> 
                                                <phase>package</phase> 
                                                <goals>
                                                        <goal>single</goal>
                                                </goals>
                                        </execution>
                                </executions>
                        </plugin>
                </plugins>
        </build>
        <dependencies>
        </dependencies>
</project>
}}}

=== dummy.xml ===
{{{#!highlight xml
<Envelope xmlns="urn:envelope">
</Envelope>
}}}

=== KeyValueKeySelector.java ===
{{{#!highlight java
package org.allowed.bitarus.xmlsign;

// https://docs.oracle.com/javase/8/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html#wp510726
// https://docs.oracle.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidAlgorithmParameterException;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.crypto.dsig.Reference;
import java.util.Collections;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import java.security.KeyException;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.w3c.dom.Document;
import javax.xml.parsers.ParserConfigurationException;
import java.io.FileNotFoundException;
import org.xml.sax.SAXException;
import javax.xml.crypto.MarshalException;
import java.io.IOException;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.w3c.dom.NodeList;
import java.lang.Exception;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import java.util.Iterator;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.KeySelectorException;
import java.util.List;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.KeySelectorResult;
import java.security.PublicKey;
import java.security.Key;


public  class KeyValueKeySelector extends KeySelector {

  public KeySelectorResult select(KeyInfo keyInfo, KeySelector.Purpose purpose,  AlgorithmMethod method,
      XMLCryptoContext context)
    throws KeySelectorException {

    if (keyInfo == null) {
      throw new KeySelectorException("Null KeyInfo object!");
    }

    SignatureMethod sm = (SignatureMethod) method;
    List list = keyInfo.getContent();

    for (int i = 0; i < list.size(); i++) {
      XMLStructure xmlStructure = (XMLStructure) list.get(i);
      if (xmlStructure instanceof KeyValue) {
        PublicKey pk = null;
        try {
          pk = ((KeyValue)xmlStructure).getPublicKey();
        } catch (KeyException ke) {
          throw new KeySelectorException(ke);
        }
        // make sure algorithm is compatible with method
        if (algEquals(sm.getAlgorithm(), pk.getAlgorithm()) ) {
          return new SimpleKeySelectorResult(pk);
        }
      }
    }
    throw new KeySelectorException("No KeyValue element found!");
  }

  boolean algEquals(String algURI, String algName) {
    if (algName.equalsIgnoreCase("DSA") &&
        algURI.equalsIgnoreCase("http://www.w3.org/2009/xmldsig11#dsa-sha256")) {
      return true;
    } else if (algName.equalsIgnoreCase("RSA") &&
        algURI.equalsIgnoreCase("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")) {
      return true;
    } else {
      return false;
    }
  }
} 
}}}

=== Main.java ===
{{{#!highlight java
package org.allowed.bitarus.xmlsign;

// https://docs.oracle.com/javase/8/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html#wp510726
// https://docs.oracle.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidAlgorithmParameterException;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.crypto.dsig.Reference;
import java.util.Collections;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import java.security.KeyException;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.w3c.dom.Document;
import javax.xml.parsers.ParserConfigurationException;
import java.io.FileNotFoundException;
import org.xml.sax.SAXException;
import javax.xml.crypto.MarshalException;
import java.io.IOException;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.w3c.dom.NodeList;
import java.lang.Exception;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import java.util.Iterator;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.KeySelectorException;
import java.util.List;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.KeySelectorResult;
import java.security.PublicKey;
import java.security.Key;

public class Main{

    public static void main(String args[]) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException,
        KeyException,ParserConfigurationException,FileNotFoundException,SAXException,MarshalException,
        IOException, XMLSignatureException,TransformerConfigurationException, TransformerException, Exception {
        DocumentBuilderFactory dbf =  DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder builder = dbf.newDocumentBuilder();
        Document doc = builder.parse(new FileInputStream("dummy.xml"));

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
        kpg.initialize(2048);
        KeyPair kp = kpg.generateKeyPair();

        XMLSignatureFactory xs = XMLSignatureFactory.getInstance();
        System.out.println(String.format("XMLSignature provider %s",xs.getProvider().getName() ) );
        DigestMethod dm = xs.newDigestMethod(DigestMethod.SHA256, null);
        Transform transform = xs.newTransform(Transform.ENVELOPED,(TransformParameterSpec) null);

        CanonicalizationMethod cm =  xs.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, 
         (C14NMethodParameterSpec) null );
        Reference ref = xs.newReference("",dm,Collections.singletonList(transform),null,null );
        SignatureMethod sm = xs.newSignatureMethod("http://www.w3.org/2009/xmldsig11#dsa-sha256", null);
        SignedInfo sigInfo = xs.newSignedInfo(cm, sm, Collections.singletonList(ref));

        KeyInfoFactory kif = xs.getKeyInfoFactory();
        KeyValue kv = kif.newKeyValue(kp.getPublic());
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); 

        XMLSignature signature = xs.newXMLSignature(sigInfo, ki); 

        DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc.getDocumentElement());
        signature.sign(dsc);

        OutputStream os = new FileOutputStream("signed.xml");
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os)); 

        //validate the signed.xml ...
        DocumentBuilderFactory otherdbf = DocumentBuilderFactory.newInstance(); 
        otherdbf.setNamespaceAware(true); 
        DocumentBuilder otherbuilder = otherdbf.newDocumentBuilder();  
        Document signedDoc = otherbuilder.parse(new FileInputStream("signed.xml")); 
        NodeList nl = signedDoc.getElementsByTagNameNS (XMLSignature.XMLNS, "Signature");
        if (nl.getLength() == 0) {
            throw new Exception("Cannot find Signature element");
        }

        //DOMValidateContext valContext = new DOMValidateContext( new KeyValueKeySelector() , nl.item(0)); 
	DOMValidateContext valContext = new DOMValidateContext( kp.getPublic() , nl.item(0)); 
        XMLSignatureFactory otherFactory = XMLSignatureFactory.getInstance("DOM"); 
        XMLSignature otherSig  = otherFactory.unmarshalXMLSignature(valContext); 
        System.out.println( String.format("Is valid? %b", otherSig.validate(valContext) ) );

        boolean sv = otherSig.getSignatureValue().validate(valContext);
        System.out.println("signature validation status: " + sv); 

        Iterator i = otherSig.getSignedInfo().getReferences().iterator();
        for (int j=0; i.hasNext(); j++) {
            boolean refValid = ((Reference)  i.next()).validate(valContext);
            System.out.println("ref["+j+"] validity status: " +  refValid);
        }

    }
}
}}}

=== SimpleKeySelectorResult.java ===
{{{#!highlight java
package org.allowed.bitarus.xmlsign;

// https://docs.oracle.com/javase/8/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html#wp510726
// https://docs.oracle.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidAlgorithmParameterException;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.crypto.dsig.Reference;
import java.util.Collections;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import java.security.KeyException;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.w3c.dom.Document;
import javax.xml.parsers.ParserConfigurationException;
import java.io.FileNotFoundException;
import org.xml.sax.SAXException;
import javax.xml.crypto.MarshalException;
import java.io.IOException;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.w3c.dom.NodeList;
import java.lang.Exception;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import java.util.Iterator;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.KeySelectorException;
import java.util.List;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.KeySelectorResult;
import java.security.PublicKey;
import java.security.Key;

public class SimpleKeySelectorResult implements KeySelectorResult{
    private Key key;

    public SimpleKeySelectorResult(Key key){
      this.key= key;
    }

    public Key getKey(){
      return this.key;
    }
}
}}}

== Add numbers console ==
{{{#!highlight sh
javac AddNumbers.java
java  -Duser.language=pt -Duser.country=PT AddNumbers
# user country and language set the decimal separator as , (comma) for Portugal
}}}

=== AddNumbers.java ===
{{{#!highlight java
import java.util.Scanner;

public class AddNumbers {

    public static double readDouble() {
        boolean gotException = true;
        double value = -1.0;

        while (gotException) {
            try {
                Scanner scanner = new Scanner(System.in);
                value = scanner.nextDouble();
                gotException = false;
            } catch (Exception ex) {
                System.out.println("Try again");
            }
        }
        return value;

    }

    public static void main(String[] args) {
        double first = -1;
        double second = -1;
        System.out.println("Input first number:");
        first = readDouble();
        System.out.println("Input second number:");

        second = readDouble();
        System.out.printf("%.2f%n",first + second);
    }
}
}}}

== Date format ==
 * https://repl.it/languages/java
{{{#!highlight java
import java.util.Date;
import java.text.SimpleDateFormat;

class Main {  
  public static void main(String args[]) { 
    Date d = new Date();  
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:MM");
    System.out.println("Hello, world! " + sdf.format(d) ); 
  } 
}
}}}