Java Proxy

Sacado de esta pagina.

Para salir a internet mediante un proxy con Java tienes las siguientes opciones:

HTTP

En la llamada a la JVM, al invocar la clase:

$ java -Dhttp.proxyHost=webcache.mydomain.com MiClaseConMetodoMain
$ java -Dhttp.proxyHost=webcache.mydomain.com -Dhttp.proxyPort=8080 MiClaseConMetodoMain
$ java -Dhttp.proxyHost=webcache.mydomain.com -Dhttp.proxyPort=8080-Dhttp.noProxyHosts=”localhost|host.mydomain.com” MiClaseConMetodoMain

En el codigo de la clase:

System.setProperty("http.proxyHost", "webcache.mydomain.com");
System.setPropery("http.proxyPort", "8080");

// Next connection will be through proxy.
URL url = new URL("http://java.sun.com/");
InputStream in = url.openStream();

// Now, let's 'unset' the proxy.
System.setProperty("http.proxyHost", null); // From now on http connections will be done directly.

HTTPS

htttps.proxyHost
https.proxyPort
http.nonProxyHosts

FTP

ftp.proxHost
ftp.proxyPort
ftp.nonProxyHosts

Configurando mas de un proxy:

$ java -Dhttp.proxyHost=webcache.mydomain.com -Dhttp.proxyPort=8080 -Dftp.proxyHost=webcache.mydomain.com -Dftp.proxyPort=8080 MiClaseConMetodoMain

SOCKS

socksProxyHost
socksProxyPort (default 1080)

Si defines un proxy HTTP y uno SOCKS,

  • tiene preferencia el HTTP.
  • El proxy SOCKS sera ignorado, para conexiones HTTP y SOCKS
  • Una conexion FTP, en esta configuracion, iria por SOCKS.

LA CLASE: java.net.Proxy

//creamos proxy HTTP
SocketAddress addr = new InetSocketAddress("webcache.mydomain.com", 8080);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);

// lo invocamos
URL url = new URL("http://java.sun.com/");
URConnection conn = url.openConnection(proxy);

// no queremos invocarlo
URL url2 = new URL("http://infos.mydomain.com/");
URLConnection conn2 = url2.openConnection(Proxy.NO_PROXY);

//creamos proxy SOCK
SocketAddress addr = new InetSocketAddress("socks.mydomain.com", 1080);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr);

// lo invocamos
URL url = new URL("ftp://ftp.gnu.org/README");
URLConnection conn = url.openConnection(proxy);


// Invocacion especifica de proxy para una conexion Socket
Socket socket = new Socket(proxy);
InetSocketAddress dest = new InetSocketAddress("server.foo.com", 1234);
socket.connect(dest);

// no queremos invocarlo
Socket socket = new Socket(Proxy.NO_PROXY);
socket.connect(new InetAddress("localhost", 1234));

LA CLASE: java.net.ProxySelector

Determina para que conexiones usar un proxy u otro

public abstract class ProxySelector {
        public static ProxySelector getDefault();
        public static void setDefault(ProxySelector ps);
        public abstract List<Proxy> select(URI uri);
        public abstract void connectFailed(URI uri,
                SocketAddress sa, IOException ioe);
}
Java Proxy

Java Hibernate DDBB, Date

En java tenemos:

  1. el paquete java.util
    • Date: representa el tiempo con precision de milisegundos
    • Calendar: clase abstrapta que provee metodos para convertir instantes de tiempo en un conjunto de campos del calendario.
    • GregorianCalendar: es una clase concreta de Calendar.
  2. el paquete java.sql
    • Date: solo guarda la fecha
    • Time: solo guarda la hora
    • Timestamp: guarda la fecha y la hora

En las bases de datos Oracle tenemos:

  • Date: guarda fecha y hora pero solo con una precision de 1 segundo
  • Time: guarda la hora.
  • Timestamp: guarda fecha y hora.

Si tratas de convertir un tipo de dato SQL.DATE en java.util.Date: tienes que usar la anotacion de JPA: @Temporal que indica que se debe hacer una conversion temporal al tipo (indicado en la anotacion), para tranformarlo al tipo especificado en la clase.

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "FECHA_DATE", nullable = false)
	public java.util.Date getFechaDate() {
		return this.fechaDate;
	}

De esta manera conservamos la fecha y la hora.

Solucion a errores:
jpa-2-0-oracle-date-has-null-time

Java Hibernate DDBB, Date

Generar el MANIFEST.MF

En referencia al post anterior. Ahora vamos a ver como se genera el manifest.

En consola

jar cfm jar-file manifest-addition input-file(s)
  • c: indica que quieres crear un fichero JAR.
  • m: indica que quieres unir informacion de un fichero en el manifest que estas creando.
  • f: indica salida a un fichero en lugar de por consola
  • manifest-addition: nombre del fichero que contiene la informacion a agregar al manifest.
  • jar-file: nombre del JAR resultante.
  • input-file(s): lista de ficheros que quieres que esten en tu JAR.

El contenido del manifest estara en UTF-8
Referencia.

Con Maven

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
				  <archive>
				    <index>true</index>
		            <manifest>
		              <addClasspath>true</addClasspath>
		            </manifest>
		            <manifestEntries>
		              <Permissions>all-permissions</Permissions>
		              <Codebase>*.prietopalacios.net</Codebase>
		              <Application-Library-Allowable-Codebase>*.prietopalacios.net</Application-Library-Allowable-Codebase>
		              <Caller-Allowable-Codebase>*.prietopalacios.net</Caller-Allowable-Codebase>
		              <Trusted-Library>true</Trusted-Library>
		              <Trusted-Library>true</Trusted-Library>
		            </manifestEntries>
		          </archive>
				</configuration>
			  </plugin>
Generar el MANIFEST.MF

Aumentar la seguridad de los MANIFEST.MF

Atributos:
Permissions: utilice el atributo «Permissions» para ayudar a evitar que alguien utilice su jar firmado en otra aplicacion y lo pueda ejecutar en un nivel de privilegio diferencte. Establezca este atributo en uno de los siguientes valores:

  • sandbox – Indica que la RIA se ejecuta en el entorno limitado de seguridad y no requiere de permisos adicionales.
  • all-permissions: todos los permisos, indica que el RIA requiere el acceso a los recursos del sistema del usuario.

RIA: Rich Internet Applications

Codebase: restringe el uso del jar a un dominio especifico:
Codebase: * todos
Codebase: *.example.com todos los subdominios del dominio example.com. Esto incluye http://www.example.com. www es un subdominio.
Codebase: 127.0.0.1, en el servidor local en todos los puertos.
Codebase: 127.0.0.1:8080, solo en el puerto 8080 del servidor local.
Application-Name: nombre de la aplicacion. Es recomendable para que el usuario pueda confiar en la aplicacion. Aparece una ventana mostrando el nombre de la aplicacion, indicando si la quieres ejecutar o no.

Application-Library-Allowable-Codebase: identifica la localizacion donde el jar sera ejecutado. Este atributo se utiliza para determinar lo que aparece en el campo Ubicación de la pregunta de seguridad que se muestra a los usuarios cuando el archivo JAR para su RIA está en una ubicación diferente a la página del archivo JNLP o HTML que se inicia el RIA.
Application-Library-Allowable-Codebase: https://host.example.com *.samplehost.com/apps
Caller-Allowable-Codebase: identifica el dominio desde el cual el codigo JavaScript puede hacer llamadas a la RIA sin indicaciones de seguridad. Establezca este atributo en el dominio que aloja el código JavaScript.
Caller-Allowable-Codebase: host.example.com 127.0.0.1
Trusted-Only: solo clases de confianaz. No ejecuta clases que no esten firmadas.
Trusted-Library: solo librerias de confianza. Firmadas.

Referencia

Aumentar la seguridad de los MANIFEST.MF

Firmar un JAR

para firmar un jar es muy sencillo, basta tener la JDK, un «key store» con su user/pass/alias/private pass.

A la hora de firmar un jar lo que se hace es:
1.- generar un hash de cada clase en SHA y lo agrega al manifest de la siguiente manera

Manifest-Version: 1.0
Implementation-Vendor: Gobierno de Espana
Implementation-Title: es.gob.afirma
Implementation-Version: build01
Application-Library-Allowable-Codebase: *
Specification-Vendor: Gobierno de Espana
Application-Name: Applet Cliente Afirma
Name: es/gob/afirma
Permissions: all-permissions
Specification-Title: Applet Cliente Afirma
Specification-Version: 3.3.1 u5
Caller-Allowable-Codebase: *
Codebase: *

Name: org/bouncycastle/jcajce/provider/digest/Whirlpool$Digest.class
SHA-256-Digest: FKks3RbQC/oJ2jlI2P9GKwYkEQdZNBOUW6dFI8uVdmM=

...

2.- Agrega unos ficheros que contienen el certificado, con el que se ha firmado, en la misma carpeta donde esta el MANIFEST.MF

En consola

jarsigner -keystore keystore.jks -storepass keystore_pass -keypass keystore_pass -signedjar jarsfirmados/LO_QUE_SEA.jar -verbose jars/LO_QUE_SEA.jar keystore_alias

Maven

			  <plugin>
				    <groupId>org.apache.maven.plugins</groupId>
				    <artifactId>maven-jarsigner-plugin</artifactId>
				    <version>1.2</version>
				    <executions>
				        <execution>
				            <id>sign</id>
				            <goals>
				                <goal>sign</goal>
				            </goals>
				        </execution>
				    </executions>
				    <configuration>
				        <keystore>/path/to/testkeystore</keystore>
				        <alias>myalias</alias>
				        <storepass>depo.root</storepass>
				    </configuration>
				</plugin>
Firmar un JAR

Como usar una libreria que no esta en el classpath

package org.wso2.carbon.classloading;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///home/shameera/Desktop/gson-2.2.4.jar")});
        Class gsonClass = urlClassLoader.loadClass("com.google.gson.Gson");
        Constructor constructor = gsonClass.getConstructor();
        Object gsonObj = constructor.newInstance();
        Method method = gsonClass.getMethod("toJson",Object.class);
        Object returnObj =  method.invoke(gsonObj, new Person());
        String jsonString = (String)returnObj;
        System.out.println(jsonString);
    }
}

Visto en….

Como usar una libreria que no esta en el classpath

Java regular expression examples

Tengo un problema con unos servicios web que me devuelven mal el xml. Cree un Interceptor para ponerlo bien. Pero es que son tan cachondos los del lado del servidor que la premisa me va cambiando.
Error inicial: axis2ns104:Server
Siguiente vez: axis2ns105:Server

Solucion Regex:

.*(axis2ns)(\d{4}|\d{3}|\d{2}|\d{1}):Server.*"
.*(axis2ns)([0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1}):Server.*
	public static final String EXAMPLE_TEST = "<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode xmlns:axis2ns105="http://schemas.xmlsoap.org/soap/envelope/">" +
			"axis2ns105:Server</faultcode><faultstring>0229 La petición ya ha sido tramitada</faultstring><detail><Atributos xmlns="http://www.map.es/scsp/esquemas/V2/soapfaultatributos"><IdPeticion>00000207</IdPeticion><TimeStamp>2014-02-24T16:37:04.967+01:00</TimeStamp><NumElementos>1</NumElementos><Estado><CodigoEstado>0229</CodigoEstado><CodigoEstadoSecundario /><LiteralError>La petición ya ha sido tramitada</LiteralError><TiempoEstimadoRespuesta>0</TiempoEstimadoRespuesta></Estado><CodCertificado>CDISFWS01</CodCertificado></Atributos></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>";
	public static void main(String[] args) {
		System.out.println(EXAMPLE_TEST.matches(".*(axis2ns)(\d{4}|\d{3}|\d{2}|\d{1}):Server.*"));
		System.out.println(EXAMPLE_TEST.matches(".*(axis2ns)([0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1}):Server.*"));
	}

Asi es como queda en mi interceptor. Con el codigo de antes simplemente sabemos que existe una coincidencia. Pero no sabemos cual. Con el siguiente codigo, descubrimos las posibles coincidencias y transformamos la cadena.

	if((currentEnvelope != null) && (currentEnvelope.matches(".*(axis2ns)(\d{4}|\d{3}|\d{2}|\d{1}):Server.*"))){
		Pattern MY_PATTERN = Pattern.compile("(axis2ns)(\d{4}|\d{3}|\d{2}|\d{1})");
		Matcher m = MY_PATTERN.matcher(currentEnvelope);
		String res = "";
		while (m.find()) {
			res= m.group();
		}
		if( ! res.equals("")){
			LOGGER.info("Debido a un bug en el mensaje SoapFault de este servicio. se procede a cambiar la etiqueta ""+res+"" por "soapenv".");
			currentEnvelope = currentEnvelope.replace(res, "soapenv");
		}
	}

Mirando por internet Vogella tiene un error, desde mi punto de vista. En un momento de su tutorial dice que

 // returns true if the string contains a number less then 300
  public boolean isLessThenThreeHundret(String s){
    return s.matches("[^0-9]*[12]?[0-9]{1,2}[^0-9]*");
  }

yo digo que eso esta mal que es:

 // returns true if the string contains a number less then 300
  public boolean isLessThenThreeHundret(String s){
    return s.matches("[012]{1}[0-9]{1,2}");
  }
Java regular expression examples

Como acceder a la pila de llamadas de la JVM

Post original de Emerson Miranda

Lo copio y pego, para no tardar en buscarlo

	public static void printStackTrace() {
		System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
		StackTraceElement[] stack = Thread.currentThread().getStackTrace();
		for(int pos=stack.length - 1; pos > 1; pos--){
			StackTraceElement elem = stack[pos];
			//se elimina el paquete del nombre de la clase
			String name = elem.getClassName().substring(elem.getClassName().lastIndexOf(".") + 1 );
			System.out.println(name + "." + elem.getMethodName() + ":"  + elem.getLineNumber());
			if(pos > 2)System.out.print("->");
		}
		System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
	}
Como acceder a la pila de llamadas de la JVM

javac classpath multiple jars

Tengo esto en mi directorio:

 CividasSara.jar
 Main.java
 cividas.jar
 cividasnotifications.jar
 ontimizeEN.jar
 ontimizeWeb.jar
 salida.out
 util-java.jar
 workflowEN.jara

Quiero compilar Main.java (crear Main.class):

WINDOWS
javac -cp "cividas.jar;cividasnotifications.java;CividasSara.jar;ontimizeEN.jar;ontimizeWeb.jar;util-java.jar;workflowEN.jar;." Main.java
LINUX
javac -cp "cividas.jar:cividasnotifications.java:CividasSara.jar:ontimizeEN.jar:ontimizeWeb.jar:util-java.jar:workflowEN.jar:." Main.java

Con lo que ya se ha generado el compilado:

 CividasSara.jar
 Main.class
 Main.java
 cividas.jar
 cividasnotifications.jar
 ontimizeEN.jar
 ontimizeWeb.jar
 salida.out
 util-java.jar
 workflowEN.jara

Ahora quiero ejecutarlo:

WINDOWS
java -cp "cividas.jar;cividasnotifications.java;CividasSara.jar;ontimizeEN.jar;ontimizeWeb.jar;util-java.jar;workflowEN.jar;." Main
LINUX
java -cp "cividas.jar:cividasnotifications.java:CividasSara.jar:ontimizeEN.jar:ontimizeWeb.jar:util-java.jar:workflowEN.jar:." Main

ANEXO I

Ejecucion de una clase, pasando un parametro como argumento. Mantenemos las librerias en el classpath.

$ java -cp "cividas.jar:cividasnotifications.java:CividasSara.jar:ontimizeEN.jar:ontimizeWeb.jar:util-java.jar:workflowEN.jar:." es.tecnocom.tsafirma.AFirmaImpl Factura-e_2013092520130925.xml

ANEXO II

El Anexo I en un script bash.

#!/bin/bash

java -cp "bduac.jar:cividas.jar:cividasnotifications.jar:CividasSara.jar:commons-beanutils.jar:commons-collections.jar:commons-digester.jar:commons-fileupload.jar:commons-io.jar:commons-lang.jar:commons-logging.jar:jboss-el-2.0.0.GA.jar:jdom-2.0.1.jar:jsf-api-2.1.3-b02.jar:jsf-impl-2.1.3-b02.jar:jstl-1.2.jar:liferay-faces-bridge-api-3.1.1-ga2.jar:liferay-faces-bridge-impl-3.1.1-ga2.jar:liferay-faces-portal-3.1.1-ga2.jar:liferay-faces-util-3.1.1-ga2.jar:log4j.jar:Main.class:Main.java:ontimizeEN.jar:ontimizeWeb.jar:recaptcha4j-0.0.7.jar:util-bridges.jar:util-java.jar:util-taglib.jar:workflowEN.jar:portal-service-6.1.1.jar:tsafirma.jar:." es.tecnocom.tsafirma.AFirmaImpl $1 >> logPruebaSelladoTiempo.log && less -Ss logPruebaSelladoTiempo.log

tambien se puede poner al final en lugar de less: «tail -2», para mostrar solo el resultado

Hay que dar permisos, y ejecutar…

chmod 775 ejecuta.sh
./ejecuta.sh ficheroASellar.xml
javac classpath multiple jars

Java proxy connection user pass


public class Prueba{
	public static void main(String[] args) {
		try {
			String ipProxy = "";
			String portProxy = "";
			String userProxy = "";
			String passProxy = "";
			System.setProperty("http.proxyHost", ipProxy);
			System.setProperty("http.proxyPort", portProxy);
			URL url = new URL("http://www.google.es");
			URLConnection uc = url.openConnection ();
			String encoded = new String (Base64.encode(new String(userProxy + ":" + passProxy ).getBytes()));
			uc.setRequestProperty("Proxy-Authorization", "Basic " + encoded);
			uc.connect();
			InputStream is = uc.getInputStream();
			
			System.out.println(getStringFromInputStream(is));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String getStringFromInputStream(InputStream is){
	      // TODO
	      return null;
	}
}

   public final static Boolean USE_PROXY = false;
   public final static Boolean IS_PROXY_AUTH = false;
   public final static String PROXY_USER = "";
   public final static String PROXY_PASSWORD = "";
   public final static String PROXY_SERVER ="";
   public final static Integer PROXY_PORT = null;
   
   private void configureConnection() {
       if(USE_PROXY) {
           System.setProperty("http.proxyHost", PROXY_SERVER);
           System.setProperty("http.proxyPort", Integer.toString(PROXY_PORT));
           if (IS_PROXY_AUTH) {
               Authenticator.setDefault(new Authenticator() {
                   @Override
                   protected PasswordAuthentication getPasswordAuthentication() {
                       return new PasswordAuthentication(PROXY_USER, PROXY_PASSWORD.toCharArray());
                   }
               });
           } else {
               Authenticator.setDefault(null);
           }
       }
   }
Java proxy connection user pass