Migrating Your Java Application from 6.x to 7.x

Deprecation notice: New functionality will only be added to the new libraries (Java 7.x). The old libraries (Java 6.x) will be officially supported until 01/15/16. After that day, Twilio will stop providing bug fixes and Support might ask you to upgrade before debugging issues.

The Twilio Java SDK has undergone significant changes from version 6.x to 7.x - we'll break down the major changes here to make migrating to the new version as painless as possible. If you're integrating Twilio in your Java app for the first time, you can skip straight to the install page.

Java Version Compatibility

The 7.x version of the Twilio SDK is compatible with Java versions 7 and higher.

Import

In prior versions of the Twilio Java SDK, you would import clients like this:

import com.twilio.sdk.LookupsClient;
import com.twilio.sdk.TwilioIPMessagingClient;
import com.twilio.sdk.TwilioRestClient;

In 7.x there is only one Twilio.

import com.twilio.Twilio;

You can initialize Twilio by using:

Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

Actions

Performing actions with 7.x has been abstracted into 5 distinct types: Fetcher, Creator, Updater, Deleter, and Reader

These actions can be created by calling the fetchcreateupdatedelete, and read static methods on the resource class. Only at this point HTTP requests are being made. This allows for better network efficiency and makes it clear when the library will perform HTTP requests. 

Fetcher

To get an instance of a resource, use a fetcher:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
...

Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Message message = Message.fetcher("SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX").fetch();

System.out.println("message sid: " + message.getSid());
// message sid: SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Creator

To make a new instance of a resource, use a creator:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
...

Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Message message = Message.creator(
    new PhoneNumber("+15558675309"),
    new PhoneNumber("+15017250604"),
    "Hello world!"
).create();

System.out.println("message body: " + message.getBody());
// message body: Hello world!

Updater

To modify an instance of a resource, use an updater:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
...

Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

// First, create a new message we can work with:
Message message = Message.creator(
    new PhoneNumber("+15558675309"),
    new PhoneNumber("+15017250604"),
    "Hello world!"
).create();

System.out.println("message sid: " + message.getSid());
// message sid: SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

System.out.println("message body: " + message.getBody());
// message body: Hello world!

// Now use an updater to modify the body of the message
// (redacting the message with empty body)
Message updatedMessage = Message.updater(message.getSid())
    .setBody("")
    .update();

System.out.println("message sid: " + updatedMessage.getSid());
// message sid: SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

System.out.println("message body: " + updatedMessage.getBody());
// message body: 

Deleter

To remove an instance of a resource, use a deleter:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
...

Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
boolean deleted = Message.deleter("SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX").delete();

System.out.println(deleted);
// true

Reader

To list resources, use a reader:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
...

Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Iterable<Message> messages = Message.reader().read();
for (Message message : messages) {
   System.out.println("message sid: " + message.getSid());
   // message sid: SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
}

Paging

7.x now handles paging for you. As you iterate over the Iterable it will fetch the next page as necessary. For further customization, you may use setPageSize on the Reader action to set the size of each page that is fetched.

Builders

7.x now uses the Builder pattern. This uses the type system to expose what parameters can be used when Creating or Updating a resource.

In older versions of the library, all that was provided to the user was:

public void update(Map<String, String> params)

While this may work, this isn't self-documenting. You don't know what you can pass into this request. For example, we could do:

Map<String, String> params = new HashMap<>();
params.put("foo", "bar");

resource.update(params);

The older versions of the Java SDK would accept this and continue on to the HTTP request that would do nothing.

Now, 7.x only allows you to pass parameters that are supported. For example, the Updater action for a Message has the following method:

public MessageUpdater setBody(String body)

This makes it clear that the only field you can update on an existing message is the Body field. On the other hand, the Creator has these methods:

public MessageCreator setStatusCallback(URI statusCallback)
public MessageCreator setStatusCallback(String statusCallback)
public MessageCreator setApplicationSid(String applicationSid)
public MessageCreator setMaxPrice(BigDecimal maxPrice)
public MessageCreator setProvideFeedback(Boolean provideFeedback)
public MessageCreator setFrom(PhoneNumber from)
public MessageCreator setMessagingServiceSid(String messagingServiceSid)
public MessageCreator setBody(String body)
public MessageCreator setMediaUrl(List<URI> mediaUrl)
public MessageCreator setMediaUrl(URI mediaUrl)
public MessageCreator setMediaUrl(String mediaUrl)

Here's an example showing how you can instantiate a Creator, set any parameters on it you wish, and then call Create:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
...

Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Message message = Message.creator(
        new PhoneNumber("+15558675309"),
        new PhoneNumber("+15017250604"),
        "This is the ship that made the Kessel Run in fourteen parsecs?"
        )
    .setMediaUrl("https://c1.staticflickr.com/3/2899/14341091933_1e92e62d12_b.jpg")
    .create();

Exposed Actions

7.x only exposes the Actions that a Resources supports. For example, the request below would be an accepted action in older versions:

LookupsClient lc = new LookupsClient(ACCOUNT_SID, AUTH_TOKEN);
PhoneNumber number = lc.getPhoneNumber("+18089263410");
number.update(new HashMap<String, String>());

This request would throw an Exception, as updating a PhoneNumber is not allowed through the Twilio API.

In 7.x, this is not allowed because there is no Updater for the PhoneNumber class.

TwiML

7.x has also moved TwiML creation to the builder pattern.

Attributes

It only allows you to set attributes that are supported by the TwiML resource. In the older versions of the SDK you could set any arbitrary attribute on an element whether or not it causes any action. For example, in the old library, this was acceptable:

Say say = new Say();
say.set("foo", "bar");

The builder in 7.x only supports the attributes that Say will accept:

public static class Builder {
    public Builder loop(int loop)
    public Builder language(Language language)
    public Builder voice(Voice voice)
    public Say build()
}

Elements

By using the builder pattern, we can guarantee valid child elements at compile time. Now you will no longer have to deal with potential TwiMLExceptions due to adding child elements.

Generating TwiML in Your Apps

For a full example of generating TwiML, check out our guides Respond to Incoming Phone Calls and Receive and Reply to SMS and MMS Messages.