Search code examples
javaemailnetbeansantmime-message

Running ant-target to send a mail via java


I´m a pretty new to ant and I´m trying to send an email within an ant-target which is called by Java. I´m using the Netbeans IDE.

Ant:

<project name="AntTargets" default="main" basedir=".">
<description>Builds, tests, and runs the project AntTargets.</description>
<import file="nbproject/build-impl.xml"/>

<target name="run" depends="jar">
    <java classpathref="AntTargets.classpath" fork="true" classname="Client" />
</target>

<target name="main">
    <echo message="******************[MAIN]******************"/>
    <property file="nbproject/build.properties"/>
    <property name="to" value="${builder}" />
    <property name="from" value="${builder}" />
    <property name="server" value="${server}" />
    <property name="port" value="${port}" />

    <mail mailhost="${server}" mailport="${port}" subject="Test build">
        <from address="${from}"/>
        <replyto address="${to}"/>
        <to address="[email protected]"/>
        <message>The build has been completed</message>
    </mail>

    <echo message="Email to ${to} from ${from} has been sent using the server ${server} on port ${port}."/>
</target>

</project>

Java:

import java.io.File;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;

public class AntTargets {

public static void main(String[] args) {
    //get new file
    File buildFile = new File("build.xml");

    //create new project
    Project p = new Project();
    p.setUserProperty("ant.file", buildFile.getAbsolutePath());
    p.init();

    //initialize helper
    ProjectHelper helper = ProjectHelper.getProjectHelper();
    p.addReference("ant.projectHelper", helper);

    //parse and execute
    helper.parse(p, buildFile);
    p.executeTarget(p.getDefaultTarget());
}   
}

When I execute the ant part directly, the properties file is found, read and works overall but the mail-part gives me this error:

Failed to send email: javax.mail.internet.MimeMessage
build.xml:16: 
java.lang.ClassNotFoundException: javax.mail.internet.MimeMessage

When I call it with java I get:

Reference AntTargets.classpath not found.
BUILD FAILED (total time: 0 seconds)

I would greatly appreciate any help and tip overall.


Solution

  • The issue is Ant doesn't know what AntTargets.classpath is.

    You must define a classpath variable and give it id="AntTargets.classpath. In this path variable you should define the physical locations of the libraries you use. (You should look to creating path variables to reduce redundancies in code, particularly when you want to use the same path in different ant targets.)

    Here's an example: Let's say that your project requires the Gson library at runtime.

    1. First, create a path for that library. Let's assume you have your libraries in a lib directory.

      <path id="library.gson-2.8.0.classpath"> <pathelement location="${basedir}/lib/gson-2.8.0.jar"/> </path>

      Do the same for other dependencies as well.

    2. Next, create a path that will contain all these dependencies, so you can refer to all the dependencies as one variable. This will be your AntTargets.classpath

      <path id="AntTargets.classpath"> <path refid="library.gson-2.8.0.classpath"/> ...... <!-- Add paths for your other dependencies by refid here--> </path>

    3. Now, when you use AntTargets.classpath Ant will know what that is and use it to run your jar.

    I notice that you use this in the run target, so if you're trying to run the Client class from your own jar, include that in your classpath as well.

    Also keep in mind that "Client" may not be enough information--you must provide the fully qualifying name of the class, including package names, e.g. something like "com.package.Client".

    EDIT:

    I just noticed the exception you're getting from running directly with Ant. You need to include the javax.mail library in this path variable we create. That should resolve that issue.

    EDIT 2:

    I seem to have misunderstood. I thought that your ant task was trying to call your Java program which would send the mail, but it couldn't since it didn't know where the javax.mail.jar is, and so I instructed you to add it to the classpath.

    But what you want to do is:

    1. Use the Ant mail task to send a mail.
    2. And in the Java you want to read the build file and execute the target that sends the mail.

    Here's some information on that: mail is an Ant Task that requires the javax.mail library, if you want to use certain arguments. Looking at a few questions like this and this, I see that you should put ${ANT_HOME}/lib, i.e. where your ant.jar is, so that Ant's classloader can pick it up and use it. In that case, if my assumption about what you want is correct, then you should be able to get rid of AntTargets.classpath, because really, your build file doesn't need to know how you call any of it's targets.