Send mail in Apache TomEE

Make javax.mail and impl as maven scope provided, as TomEE comes with geronimo mail implementation.

Also use resource injection of mail session:

https://dwuysan.wordpress.com/2016/02/17/sending-email-on-apache-tomee/

(If mail account is Gmail, turn ON ‘Allow less secure apps’)

In Tomee.xml:

<?xml version="1.0" encoding="UTF-8"?>
<tomee>
    <!-- see http://tomee.apache.org/containers-and-resources.html -->
 
    <!-- activate next line to be able to deploy applications in apps -->
    <!-- <Deployments dir="apps" /> -->
    <Resource id="tomee/mail/GMailSMTP" type="javax.mail.Session">
    mail.smtp.host=smtp.gmail.com
    mail.smtp.starttls.enable=true
    mail.smtp.port=587
    mail.transport.protocol=smtp
    mail.smtp.auth=true
    mail.smtp.user=<!-- your email address -->
    password=<!-- your password, and not 'mail.smtp.password' -->
    </Resource>
</tomee>

Injection of resource:

@Stateless
@LocalBean
@Path(value = "workline")
public class MailService {
    @Resource(mappedName = "java:comp/env/tomee/mail/GMailSMTP")
    private Session smtpSession;
 
    public boolean sendMail() throws NamingException {
        final Message message = new MimeMessage(this.smtpSession);
        try {
            message.setRecipients(Message.RecipientType.TO, new Address[]{
                new InternetAddress("someone@gmail.com")
            });
            message.setSubject("Email from TomEE");
            message.setSentDate(new Date());
            message.setText("Email from TomEE");
            Transport.send(message);
        } catch (Exception e) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, e);
            return false;
        }
        return true;
    }
}

A raw implementation:

package com.origami.rpp.util;

import com.origami.config.SisVars;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 *
 * @author Origami
 */
public class Email {

    protected List<File> adjuntos = new ArrayList<>();
    protected String usuarioCorreo = SisVars.correo;
    protected String password = SisVars.pass;
    protected String rutaArchivo1;
    protected String nombreArchivo1;
    protected String rutaArchivo2;
    protected String nombreArchivo2;
    protected String destinatario;
    protected String copiaOcultaBCC;
    protected String copiaCC;
    protected String asunto;
    protected String mensaje;

    public Email(String destinatario, String copiaOcultaBCC, String copiaCC, String asunto, String mensaje, List<File> files) {
        this.destinatario = destinatario;
        this.copiaOcultaBCC = copiaOcultaBCC;
        this.copiaCC = copiaCC;
        this.asunto = asunto;
        this.mensaje = mensaje;
        if(files != null) this.adjuntos = files;
    }

    public Email(String destinatario, String asunto, String mensaje, List<File> files) {
        this(destinatario, null, null, asunto, mensaje, files);
    }

    public boolean sendMail() {
        try {
            //INGRESO DE LAS POROPIEDADES DE LA CONEXION
            Properties props = new Properties();
            props.setProperty("mail.transport.protocol", "smtp");
            props.setProperty("mail.smtp.host", SisVars.smtp_Host);
            props.setProperty("mail.smtp.starttls.enable", "true");
            props.setProperty("mail.smtp.port", SisVars.smtp_Port);
            props.setProperty("mail.smtp.user", usuarioCorreo);
            props.setProperty("mail.smtp.auth", "true");
            //INSTANCIA DE LA SESSION
            Session session = Session.getInstance(props, null);
            //CUERPO DEL MENSAJE
            MimeMessage mimeMessage = new MimeMessage(session);
            mimeMessage.setFrom(new InternetAddress(usuarioCorreo, "EMPRESA PUBLICA MUNICIPAL DEL REGISTRO DE LA PROPIEDAD DEL CANTON PORTOVIEJO EP"));
            mimeMessage.setSubject(asunto);
            mimeMessage.setSentDate(new Date());
            mimeMessage.addRecipients(Message.RecipientType.TO, InternetAddress.parse(destinatario));
            if (copiaOcultaBCC != null) {
                mimeMessage.addRecipients(Message.RecipientType.BCC, InternetAddress.parse(copiaOcultaBCC));
            }
            if (copiaCC != null) {
                mimeMessage.addRecipients(Message.RecipientType.CC, InternetAddress.parse(copiaCC));
            }
            //TEXTO DEL MENSAJE
            MimeBodyPart texto = new MimeBodyPart();
            texto.setText(mensaje);
            //CONTENEDOR DE LAS PARTES
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(texto);
            //ADJUNTAR LOS ARCHIVO EN PARTES
            MimeBodyPart file;
            for (File f : adjuntos ) {
                file = new MimeBodyPart();
                file.attachFile(f.getAbsolutePath());
                multipart.addBodyPart(file);
            }
            //AGREGAR MULTIPART EN CUERPO DEL MENSAJE
            mimeMessage.setContent(multipart);
            // ENVIAR MENSAJE
            Transport transport = session.getTransport("smtp");
            transport.connect(usuarioCorreo, password);
            transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
            transport.close();
            
            
            
        } catch (MessagingException ex) {
            Logger.getLogger(Email.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {
            Logger.getLogger(Email.class.getName()).log(Level.SEVERE, null, e);
        }
        return true;
    }

}
Advertisements

Fix JMX RMI port configuration

Set the following ports in java command line:

com.sun.management.jmxremote.port
com.sun.management.jmxremote.rmi.port

Example on unique port 9229:

-Djava.net.preferIPv4Stack=true 
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9229 
-Dcom.sun.management.jmxremote.rmi.port=9229
-Djava.rmi.server.hostname=190.57.138.218 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

In Tomcat / TomEE set them in bin/setenv.sh file:

export CATALINA_OPTS="$CATALINA_OPTS -server -Xmx6000m -Xms512m -XX:MaxPermSize=400m -Djava.net.preferIPv4Stack=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9229 -Dcom.sun.management.jmxremote.rmi.port=9229 -Djava.rmi.server.hostname=190.57.138.218 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

export JAVA_OPTS="-client -Xms8m -Xmx128m -XX:MaxPermSize=64m -Djava.net.preferIPv4Stack=true"

Due to a bug this doesnt works in java versions <= 1.7.0_51. Please upgrade the java/JDK version.

Resources:

http://stackoverflow.com/questions/20884353/why-java-opens-3-ports-when-jmx-is-configured/21552812#21552812

Json Rest Client to beans with Jodd-http and Jackson


package gob.documental.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import gob.documental.DocsVars;
import gob.documental.web.acl.UserDataJson;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;

/**
 *
 * @author Fernando
 */
public class AclServiceWs implements AclService{
    
    @Override
    public UserDataJson login(String user, String pass){
        
        UserDataJson userData = new UserDataJson();
        
        String urlRest = DocsVars.sgmUrl + "rest/acceso/auth/userName/"+user+"/password/"+pass+"/get";
        Logger.getLogger(AclServiceWs.class.getName()).log(Level.INFO, "URL: {0}", urlRest);
        
        HttpRequest httpRequest = HttpRequest.get(urlRest);
        HttpResponse response = httpRequest.send();
        
        ObjectMapper mapper = new ObjectMapper();
        String bodyResp = response.bodyText();
        
        try {
            Logger.getLogger(AclServiceWs.class.getName()).log(Level.INFO, bodyResp);
            userData =  mapper.readValue(bodyResp, UserDataJson.class);
        } catch (IOException ex) {
            Logger.getLogger(AclServiceWs.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        // comprobar usuario existente:
        if(userData.getId()!=null){
            return userData;
        }
        
        return null;
    }
    
}

Clean and fix html with HtmlCleaner java library

package com.origami.sgm.util;

import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.SimpleHtmlSerializer;
import org.htmlcleaner.TagNode;

/**
 *
 * @author Fernando
 */
public abstract class HtmlUtil {
    
    public static String cleanHtml(String htmlText){
        
        HtmlCleaner cleaner = new HtmlCleaner();
        
        CleanerProperties props = cleaner.getProperties();
        
        TagNode node = cleaner.clean(htmlText);
        
        SimpleHtmlSerializer htmlSerializer = new SimpleHtmlSerializer(props);
        
        // remove <?xml definition tag:
        String htmlResult = htmlSerializer.getAsString(node).replaceAll("\\<\\?xml(.+?)\\?\\>", "").trim();
        
        return htmlResult;
    }
    
}

Analize java annotations of getter method by property name

Get getter Method by property name

    protected Method methodGetter(String nombre){
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(enteClass);

            for(PropertyDescriptor cadaProp : beanInfo.getPropertyDescriptors()){
                if(cadaProp.getName().equals(nombre)){
                    return cadaProp.getReadMethod();
                }
            }
            
        } catch (IntrospectionException ex) {
            Logger.getLogger(PropiedadCrud.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return null;
    }

Get Annotation object (null if doesn’t exist)

    Method metodo = this.methodGetter();
    FmField fmField = metodo.getAnnotation(FmField.class);

JSF date/time converters for system’s timezone

JSF date/time converters defaults by specification to UTC timezone. If you want to use a different timezone, then you really need to specify it in the converter yourself. Or, if you have 100% control over the production runtime environment, then set its system timezone to the desired timezone and add the following context parameter to web.xml:

<context-param>
    <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
    <param-value>true</param-value>
</context-param>

This way JSF will use the system’s timezone as obtained by TimeZone#getDefault() as converter’s default timezone.

Please note that the java.util.Date object by itself also does not store any timezone information. It also always defaults to UTC timezone. Keep this in mind when processing submitted date/times.

Thanks to Ricardo (Metal Apache) Andrade for the link.

link: http://stackoverflow.com/questions/7490954/set-a-default-time-zone-for-fconvertdatetime

 

Primefaces javascript RemoteCommand parameters

 

From BalusC:
Since PrimeFaces version 3.3 the syntax is as follows (copypasted from 3.3 users guide):

3.81 RemoteCommand

Passing Parameters

Remote command can send dynamic parameters in the following way;

increment([{name:'x', value:10}, {name:'y', value:20}]);

This way offers the possibility to specify multiple values on a single parameter name. Parameters with single values like above are available the same way as the old way:

@ManagedProperty("#{param.x}")
private int x;
@ManagedProperty("#{param.y}")
private int y;

(note: you can use Integer in Mojarra, but not in MyFaces, this is further completely unrelated to <p:remoteCommand>)

or in method of a broader scoped bean:

Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
int x =Integer.valueOf(params.get("x"));
int y =Integer.valueOf(params.get("y"));

If you need to specify a parameter with multiple values, then you could do it as follows:

functionName([{name:'foo', value:'one'},{name:'foo', value:'two'},{name:'foo', value:'three'}]);`

with in a request scoped bean:

@ManagedProperty("#{paramValues.foo}")
private String[] foos;

or in method of a broader scoped bean:

Map<String,String[]> paramValues = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValuesMap();
String[] foos = paramValues.get("foo");

 

Callback Parameters

You can add as many callback parameters as you want with addCallbackParam API.

Each parameter is serialized as JSON and accessible through args parameter so pojos are also supported just like primitive values. Following example sends a pojo called User that has properties like firstname and lastname to the client in addition to isValid boolean value.
public void validate() {
//isValid = calculate isValid
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.addCallbackParam(“isValid”, true or false);
requestContext.addCallbackParam(“user”, user);
}
<script type=”text/javascript”>
function handleComplete(xhr, status, args) {
var firstname = args.user.firstname;
var lastname = args.user.lastname;
}
</script>
By default validationFailed callback parameter is added implicitly if validation fails.

 

Fileuploader only uploads first file if an BlockUI component is in the same view, Primefaces

Environment:
I´m using common Primefaces 3.5. with JSF 2.1 and JDK 1.7.
Application server is glassfish 3.

Problem:
If i use an UIBlock component in the same view as the fileuploader, 
the fileuploader only processes the first file.
Testet with different commons-io and commons-fileuploader libs.
Testet on single view with only these two components in it.

Workaround:
After removing the UIBlock Element the fileuploader is working fine again.

Greetings

Martin


Jul 10, 2013

#1 dpearson…@gmail.com

Check out the last post in this topic. 
I had a block UI file upload problem even when they weren't in the same dialog. 
It seems they are incompatible. This fixed my issue so maybe yours is related.

http://forum.primefaces.org/viewtopic.php?f=3&t=23008

I overloaded the function in my own primefaces control javascript file with
Primefaces.widget.BlockUI.prototype.bindTriggers = function {
code from that post
}

Being able to do this is pretty handy b/c you don’t have to break open the primefaces
source and update it yourself.
I’ve had to do this for a few other issues as well that just needed some if checks.

 

The post:

I had the same problem. I think it is related to the fileUpload more than blockUI cause the ajaxComplete triggered has no parameter in it…Anyway i resolved this with a patch to the primefaces.js modifying the blockUI widget bindTriggers method like this:

Code:
bindTriggers:function(){var a=this,b=this.cfg.triggers.split(",");$(document).bind("ajaxSend",function(d,f,c){if(c){if($.inArray(c.source,b)!=-1){a.show()}}});$(document).bind("ajaxComplete",function(d,f,c){if(c){if($.inArray(c.source,b)!=-1){a.hide()}}})}
bindTriggers:function(){
var a=this,b=this.cfg.triggers.split(",");
$(document).bind("ajaxSend",function(d,f,c){if(c){if($.inArray(c.source,b)!=-1){a.show()}}});
$(document).bind("ajaxComplete",function(d,f,c){if(c){if($.inArray(c.source,b)!=-1){a.hide()}}})
}

 

 

 

Forcefully initializing proxies in Hibernate

Forcefully initializing proxies in Hibernate

As we have seen, The Hibernate Entities that we load in a persistence context may be made of proxies and collection wrappers. The simplest way to initialize these proxies would be to call any of the data getter methods (except Identifier).
Consider that you have loaded an object. You now need to detach the object and return it to a different function outside the persistence context.

public static void test() {
    Session session = sessionFactory.openSession();
    System.out.println("Loading a shelf object");
    Shelf shelf = (Shelf) session.load(Shelf.class, shelfId);
    session.close();
    useDetached(shelf);
}
    
public static void useDetached(Shelf shelf) {
    //do operations here
    System.out.println("Shelf code is " + shelf.getCode());
}

The above code results in the infamous exception

Exception in thread "main" org.hibernate.LazyInitializationException: could not
initialize proxy - no Session

The way around would be to initialize the entities needed.

public static void test() {
    Session session = sessionFactory.openSession();
    System.out.println("Loading a shelf object");
    Shelf shelf = (Shelf) session.load(Shelf.class, shelfId);
    shelf.getCode();// this will load the object
    session.close();
    useDetached(shelf);
}

This will make the code work, but looks very stupid and will frankly cause some other developer to curse you one day. Hibernate provides a better method to initialize objects. Hibernate.initialize()

public static void testInitializeProxy() {
    Session session = sessionFactory.openSession();
    System.out.println("Loading a shelf object");
    Shelf shelf = (Shelf) session.load(Shelf.class, shelfId);
    System.out.println("calling Hibernate.initialize() on the shelf");
    Hibernate.initialize(shelf);
    System.out.println("executed Hibernate.initialize() on shelf");
    session.close();
}

The logs are as below:

Loading a shelf object
calling Hibernate.initialize() on the shelf
Hibernate: 
    /* load com.collection.smart.Shelf */
     select
        shelf0_.ID as ID0_0_,
        shelf0_.CODE as CODE0_0_ 
    from
        SHELF shelf0_ 
    where
        shelf0_.ID=?
executed Hibernate.initialize() on shelf

This method is a very rare necessity. To lazily initialize a collection:

public static void testInitializeCollection() {

    Session session = sessionFactory.openSession();
    Shelf shelf = (Shelf) session.load(Shelf.class, shelfId);
    Set<Book> books = shelf.getAllBooks();
    System.out.println("calling Hibernate.initialize() on set ");
    Hibernate.initialize(books);
    System.out.println("executed Hibernate.initialize() on the set ");
    session.close();
    for(Book book: books) {
        System.out.println("Book class is " + book.getClass());
    }    
}

The logs indicate the output:

Hibernate: 
    /* load com.collection.smart.Shelf */
    select
        shelf0_.ID as ID0_0_,
        shelf0_.CODE as CODE0_0_ 
    from
        SHELF shelf0_ 
    where
        shelf0_.ID=?
calling Hibernate.initialize() on set 
Hibernate: 
    /* load one-to-many com.collection.smart.Shelf.allBooks */
     select
        allbooks0_.SHELF_ID as SHELF3_1_,
        allbooks0_.ID as ID1_,
        allbooks0_.ID as ID1_0_,
        allbooks0_.Name as Name1_0_,
        allbooks0_.shelf_id as shelf3_1_0_ 
    from
        BOOK allbooks0_ 
    where
        allbooks0_.SHELF_ID=?
executed Hibernate.initialize() on the set 
Book class is class com.collection.smart.Book
Book class is class com.collection.smart.Book

For the collection scenario the java docs comes with a warning:
Note: This only ensures initialization of a proxy object or collection; it is not guaranteed that the elements INSIDE the collection will be initialized/materialized. 
In our case, as the SQL Query was executed the records were initialized successfully. I even used a smart collection to see if the entities would be loaded. However in that case too, on calling the initialize method Hibernate loaded all the Book entities and not Book proxies.

Select in Criteria using SQL, Hibernate

Select in Criteria using SQL

In an earlier post we saw how Criteria provided us with the ability to add restrictions in the where clause using pure SQL. The next question would then be if Criteria allows SQL in select clause ?
I tested the below code:

public static void testSqlSelect() {
    final Session session = sessionFactory.openSession();
    Criteria criteria = session.createCriteria(Entity.class);
    int id = 4;
    criteria.add(Restrictions.eq("id", id));
    criteria.setProjection(Projections
        .projectionList()
            .add(Projections.property("name"))
            .add(Projections.property("master"))
            .add(Projections
                .sqlProjection(
                    "(select count(c.id) from CHILD_ENTITY c INNER JOIN ENTITY e on c.ENTITY_ID = e.id "
                    + "where e.id = " + id + ") as childCount",
                    new String[] { "childCount" },
                    new Type[] { Hibernate.LONG }
                )
            )
        );
    List<Object[]> rows = criteria.list();
    for (Object[] row : rows) {
        System.out.println(" Entity is " + row[0] + " and " + row[1] + " no of kids : " + row[2]);
    }
    session.close();
}

In this the normal Criteria returns me the details of Entity and its Master. But I have added a separate SQL query that will return me the number of ChildEntities associated with the particular record. The output of the code is as below:

    select
        this_.NAME as y0_,
        this_.MASTER_ID as y1_,
        (select
            count(c.id) 
        from
            CHILD_ENTITY c 
        INNER JOIN
            ENTITY e 
                on c.ENTITY_ID = e.id 
        where
            e.id = 4) as childCount 
    from
        ENTITY this_ 
    where
        this_.ID like ?
Hibernate: 
    /* load com.model.Master */ select
        master0_.ID as ID2_0_,
        master0_.DATA as DATA2_0_ 
    from
        ENTITY_MASTER master0_ 
    where
        master0_.ID=?
 Entity is entity100 and [Master] : ( id 2 , data : master No 2 )] no of kids : 1

As can be seen the SQL query was embedded within the select clause. The query being SQL, it could refer to any table or column whether known or unknown to Hibernate. The other parameters are used to update Hibernate with details of the return type from the statement. As it is an array, the inner select is capable of returning multiple columns.
An important thing to keep in mind though is that the sub-query is not allowed to return more than one row. This will result in an SQL exception if my entity row has more than one Entity_Child associations:

    select
        this_.NAME as y0_,
        this_.MASTER_ID as y1_,
        (select
c.id 
        from
            CHILD_ENTITY c 
        INNER JOIN
            ENTITY e 
                on c.ENTITY_ID = e.id 
        where
            e.id = 2) as childCount 
    from
        ENTITY this_ 
    where
        this_.ID=?

Source: http://learningviacode.blogspot.com/2013/04/select-in-criteria-using-sql.html