Accessing POP3 & IMAP From AppEngine

A quick note about accessing IMAP and POP3 servers from AppEngine: you need to include the JavaMail libraries and import everything from javax.mail and javax.mail.internet.

If you need to streamline the amount of JARs bundled with your application, you can also select individual protocol provider JARs.

Here’s example code to extract emails from a POP3 store:

    Properties properties = new Properties();
    properties.put("mail.host", host);
    properties.put("mail.store.protocol", "pop3s");
    properties.put("mail.pop3s.auth", "true");
    properties.put("mail.pop3s.port", port);
    Session session = Session.getDefaultInstance(properties);
    Store store = session.getStore();
    //With a POP3 store available, connect to the given account.
    store.connect(host, user, password);
    //Open up the inbox folder, and give ourselves read/write privilegese.
    Folder folder = store.getFolder("inbox");
    folder.open(Folder.READ_WRITE);
    //Collect messages.
    Message[] messages = folder.getMessages();
    System.out.println(messages.length);
    for (int i = 0; i < messages.length; i++) {
        //Extract message.
        MimeMessage message = (MimeMessage)messages[i];

From here, you can extract the from address and the subject line from the MimeMessage. Remember that the Sockets API requires that you have billing enabled on your application.

Writing To The Blobstore Using The Files API

A short code snippet showing how to write data to the Blobstore using the experimental Files API.

FileService file_service = FileServiceFactory.getFileService();
AppEngineFile file = file_service.createNewBlobFile(mime_type, filename);
FileWriteChannel write_channel = file_service.openWriteChannel(file, true);
ByteBuffer buffer = ByteBuffer.wrap(byte_array);
write_channel.write(buffer);
write_channel.closeFinally();

 

TaskTooLargeError

Google App Engine has an upper limit on how much data you can put into a task – a maximum of 100 KB. This includes everything within an individual task such as parameters, payload, the request URL, etc.

To get around this error, store any large pieces of information within an entity in the datastore. You can then pass the entity’s ID as a task parameter and pull out the entity’s data during task processing.

Geolocation With App Engine

One of the best parts of hosting with App Engine is the free geolocation service it provides. Every incoming request has special AppEngine location headers added to it.

For instance, here’s how to find out the user’s city (req is the servlet’s HttpServletRequest object):

 String city = req.getHeader("X-AppEngine-City");

Other geolocation information is available as well: the user’s country (X-AppEngine-Country), the region of that country (X-AppEngine-Region), and the nearest city’s latitude and longitude (X-AppEngine-CityLatLong).

Sending Mail With The Java Low Level API

Code example on how to send mail using the Java low level API. This code generates the appropriate From address based on your application’s ID.

MailService.Message message = new MailService.Message();
message.setSubject(subject);
message.setTextBody(body);
String application_id = SystemProperty.applicationId.get();
String sender = "donotreply@" + application_id + ".appspotmail.com";
message.setSender(sender);
MailServiceFactory.getMailService().sendToAdmins(message);

Your project must be configured to use a JDK in order to use JSPs

Whenever I configure a new Eclipse install, I get a strange error the first time I use JSP files. Eclipse complains that I have to configure it to use a JDK, even though a JDK is obviously installed (Otherwise how could it compile Java class files?).

The fix is to go to Preferences – Java – Installed JREs. Click on the first JRE entry, press Edit, and navigate to the base JDK directory. After you save the setting restart Eclipse, and everything will work.