Envio de email com anexo

Bom dia senhores.

Tenho a seguinte situação, tenho uma aplicação web feita com o VRaptor 3, funcionando .

Surgiu a necessidade de enviar e-mail .

Busquei alguns exemplos, implementei e funcionou. Porém, agora estou quebrando a cabeça é para enviar esse e-mail com anexo.

Montei o formulário, criei o método no meu Controller e dá erro. Observei que se eu colocar o caminho do anexo, funciona, agora simplesmente recebendo do formulário (percebi que o formulário não envia o caminho) , dá erro.

Como vocês fazem? Nesse caso eu teria que fazer o upload do arquivo para depois anexar?

Se puderem me mostrar algum exemplo, me ajudaria e muito.

Obrigado.

Seguinte minha praia é aplicações desktop, porém eu montei uma classe completa que pode ser util para vc, ela recebe anexos do tipo byte e envia via email sem nenhum problema

import entidades.Anexo;
import entidades.Contato;
import eu.medsea.mimeutil.MimeUtil;
import java.awt.HeadlessException;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.PasswordAuthentication;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import javax.swing.JProgressBar;

/**
 *
 * @author clemerson.medeiros
 */
public class EnviarEmail extends ThreadCommand {

    public EnviarEmail(JProgressBar progress) {
        super(progress);
    }
    private List<Contato> to;
    private String subject;
    private String message;
    private List<Anexo> anexos;

    public void sendMail(List<Contato> to, String subject, String message, List<Anexo> anexos) {
        this.to = to;
        this.message = message;
        this.subject = subject;
        this.anexos = anexos;
    }

    @Override
    public void execute() {
        Properties props = new Properties();
        props.put("mail.transport.protocol", "smtp"); //define protocolo de envio como SMTP
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", "smtp.gmail.com"); //server SMTP do GMAIL
        props.put("mail.smtp.auth", "true"); //ativa autenticacao
        props.put("mail.smtp.user", "*****SeuEmailAQUI****"); //usuario ou seja, a conta que esta enviando o email (tem que ser do GMAIL)
        props.put("mail.debug", "false");
        props.put("mail.smtp.port", "465"); //porta
        props.put("mail.smtp.socketFactory.port", "465"); //mesma porta para o socket, padrão do Gmail
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");
        Session session = Session.getInstance(props, new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("*****SeuEmailAQUI****", "Senha do Email aqui");
            }
        });
        //  session.setDebug(true); //Habilita o LOG das ações executadas durante o envio do email
        Message msg = new MimeMessage(session);
        try {
            msg.setFrom(new InternetAddress("*****SeuEmailAQUI (de novo)****"));
            msg.setSubject(subject);
            Multipart mp = new MimeMultipart();
            MimeBodyPart mbp1 = new MimeBodyPart();
            mbp1.setText(message); // adiciona a mensagem 
            mp.addBodyPart(mbp1);
            if (anexos.size() > 0) { // verifica se possui anexos
                for (Anexo anexo : anexos) { // este for adiciona ao mp todos os anexos listados
                    mbp1 = new MimeBodyPart(); // reconstroi o MimeBody para que possa ser usado na implementção dos anexos
                    mbp1.setDisposition(Part.ATTACHMENT);
                    mbp1.setDataHandler(new DataHandler(new ByteArrayDataSource(anexo.getImagem(), getMimeType(anexo.getImagem()))));
                    mbp1.setFileName(anexo.getNomeAnexo());
                    mp.addBodyPart(mbp1); // adiciona ao Mp o anexo convertido
                }
            }
            msg.setContent(mp); // adiciona a mensagem todo o mp gerado pelo texto + anexo
            for (Contato to1 : to) { // pega lista de contatos 
                progress.setValue(80);
                progress.setString("Enviando para " + to1.getEmail()); // define o jprogressbar da janela de enviarEmail_i
                msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to1.getEmail())); // define destinatario
                msg.saveChanges(); // salva a mensagem - importante ser depois de definir destinatario
                Transport.send(msg); // envia mensagem - Isso demora bastante
                progress.setString("Enviado com Sucesso!!");
                progress.setValue(100);
            }
        } catch (MessagingException | HeadlessException e) { // caso ocorra erro no envio ou criação de mensagem
            progress.setValue(0);
            System.out.println(">> Erro: Envio Mensagem " + e.getMessage());
        }
    }

    private String getMimeType(byte[] file) { // este método verifica e possibilita diversos tipos de arquivos como .doc ou .xls
        try {
            MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
            eu.medsea.mimeutil.MimeType m = MimeUtil.getMostSpecificMimeType(MimeUtil.getMimeTypes(file));
            MimeUtil.unregisterMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
            return m.toString();
        } catch (OutOfMemoryError a) {
            System.out.println(a.getMessage());
            return "";
        }
    }
}

Na classe anexo:

public class Anexo {
    
    public Anexo(){
    }
    
    private Short idAnexo;
    private Incidente codIncidente;
    private String nomeAnexo;
    private byte[] imagem;
 
//GETTERS e SETTERS
   
}

Na classe Contato:

public class Contato {

    private Short codigo;
    private String nome;
    private String email;
    private boolean marcar;

public Contato() {
}

// Ja sabe... Getters e setters
}

Para enviar a mensagem coloque o seguinte código no botão:

EnviarEmail enviar = new EnviarEmail(jProgressBar1);
Thread t1 = new Thread(enviar);
enviar.sendMail(table.listaMarcados(), assunto, texto, anexos);
t1.start();

E para quem ficou em duvida sobre pq chamo a classe Thread, é que eu coloquei uma barra de carregamento, pq sim, porem inutil, mas se quiserem a classe:

import javax.swing.JProgressBar;

public abstract class ThreadCommand implements Runnable {
    protected JProgressBar progress;

    public ThreadCommand(JProgressBar progress) {
        super();
        this.progress = progress;
    }

    @Override
    public void run() {
        execute();
    }

    public abstract void execute();
}

IMPORTANTE: eu uso g-mail, e para enviar pelo g-mail o seu g-mail(repeti dnv) deve estar habilitado para utilizar de programas não confiáveis.