Friday, April 25, 2008

EDI In XML

HL7 ---health level 7

HL 7 messaging converted to xml

The Health Insurance Portability and Accountability Act of 1996 (HIPAA)

HIPAA standardize specific transaction numbers for transaction

1) Supporting Healthcare EDI Standards (X12 & HL7)

DataDirect XML Converters provide robust support for X12 electronic data interchange (EDI) and Health Level Seven (HL7) clinical and administrative healthcare data standards. Healthcare payers and providers use DataDirect XML Converters to help expedite the following scenarios and deliver timely and effective patient care:

§ Benefit enrollment and maintenance

§ Coverage eligibility and core authorizations

§ Claims submissions and status inquiries

§ Claims payment and notifications

§ Clinical care management

We’ve created two new tutorials to get you started quickly with these standards.

§ Converting from HL7 2.x to 3.x

§ Translating X12 documents to XML

2) Using XQuery with MySQL

Users with MySQL database deployments can now take advantage of all the benefits of DataDirect's XQuery engine. That means that finally MySQL users have access to a standard way (XQuery) to get access to their data as XML.

To see how all this works, and how MySQL users can take advantage of this opportunity, we have created a few examples on our web site; see how easy it is to use XQuery to:

§ Extract data from MySQL as XML

§ Aggregate it with XML documents or EDI documents

§ Update your MySQL data

3) XML-based Data Services Workshop

This spring we'll be bringing you Building Data Services Providing Access to Heterogeneous Data Sources – a workshop where we'll be writing, testing and deploying a solution for a typical data services scenario using XML and XQuery. The workshop covers:

§ Transforming XML documents into user-defined formats

§ Aggregating XML documents with relational data

§ Consuming Web services in XQuery

§ Exposing XQuery as data services

§ Integrating with non-XML B2B standards, like EDI

§ Adhering to XML industry standards, such as ACORD for insurance

Order Series (ORD )(810 invoice ,832sales,850PO,855PO ackaledge,

856 ship notice,

865 POchange ,

857 shipment notice,

880 gracery pruduct invoice ,

865 po change ,

881 Mfg coopen,881

Tax Services Series (TAX (from 150 ---

Materials Handling Series (MAT)511 requisition,517 merial validation,527 material due in and receipt ,843 req,res quotation

845 price status 847 material cliaims,851 asset schedule ,893 item info req

Tax Services Series (TAX)

149 notice on tax ,151,152 Statistical Government Information ,

155 business credit report ,

157notice to power attorney ,

170 Revenue Receipts Statement ,521

813 electonic filling of tax return data

826 Tax Information Exchange

Warehousing Series (WAR)

883 Market Development Fund Allocation,

884 Market Development Fund Settlement,

886 Customer Call Reporting ,

891 Deduction Research Report

945 Warehouse Shipping Advice

947 Warehouse Inventory Adjustment Advice

943 Warehouse Stock Transfer Shipment Advice

944 Warehouse Stock Transfer Receipt Advice

Financial Series (FIN)

810 invoice

248 account assignment

812 credit /debit adjustment

818 Commission Sales Report

819 Operating Expense Statement

820 PO

822 Account Analysis

821 Financial Information Reporting

859 Freight Invoice

823 Lockbox

824 Application Advice

827 Financial Return Notice

828 Debit Authorization

Government Series (GOV)

150 Tax Rate Notification

151 Electronic Filing of Tax Return Data Acknowledgment

152 152 Statistical Government Information

153 Uniform Commercial Code Filing

176 Court Submission

208 voter reg info

Manufacturing Series (MAN)

196,830,844

Delivery Series (DEL)

219,220,222 for logistics, 862 shipping schedule

882 direct store

Insurance/Health Series (INS)

100 Insurance Plan Description

112 Property Damage Report

148 Report of Injury, Illness or Incident

186 Insurance Underwriting Requirements Reporting

252 Insurance Producer Administration

252 Underwriting Information Services

268 Annuity Activity

267 Individual Life, Annuity and Disability Application

270 Eligibility, Coverage or Benefit Inquiry

274 Health Care Provider Information

272 Property and Casualty Loss Notification

273 Insurance/Annuity Application Status

276 Health Care Claim Status Request

275 Patient Information

837 Health Care Claim

288 Wage Determination

500 Medical Event Reporting

277 Health Care Claim Status Notification

820 Premium Payments

925 Claim Tracer

928 Automotive Inspection Detail

924 Loss or Damage Claim - Motor Vehicle

Miscellaneous ANSI X12 Transactions Series (MIS)

101 Name and Address Lists

997 Functional Acknowledgment

868 Electronic Form Structure

---------------------------------------------------

ASC X12

ASC X12 (also known as ANSI ASC X12) is the official designation of the U.S. national standards body for the development and maintenance of Electronic Data Interchange (EDI) standards. The group was founded in 1979, and is an accredited standards committee under the American National Standards Institute (ANSI). The acronym stands for "American National Standards Institute Accredited Standards Committee X12", with the designation of X12 being a sequential designator assigned by ANSI at the time of accreditation with no other significance.

ASC X12 has sponsored more than 315 X12-based EDI standards and a growing collection of X12 XML schemas for health care, insurance, government, transportation, finance, and many other industries. ASC X12's membership includes 3,000+ standards experts representing over 350 companies from multiple business domains.

HL7 Messaging System


With every passing day, the market pressure to be a "Real-time Enterprise" is building slowly but surely on the Healthcare Organizations (HCO). This is in addition to the governmental regulation compliance on patient privacy, decreased government reimbursement for the services provided and ever-presentcompetition in the healthcare markets to take away the market share of an HCO. With the access to the information becoming, "anytime, anywhere" via the internet, the patients will start expecting personalized real-time access to their health information to make better decisions about their health and healthcare purchases.

Our technology meet today's HCO challenges

To meet these challenges, an HCO has to be agile and nimble with the ability to respond quickly to the changes to improve the patient care while reducing the cost. This requires that the HCO's information systems be integrated to provide the right information to the right provider on time. Many of HCOs today use the industry standard Health Level 7 (HL7) and X12 messaging mechanism to exchange patient care information among various systems used in the organization.

Though HL7 is supposed to be an industry-standard, the variations and the customizations on the HL7 message definitions do not make the implementation of HL7 any easier. Combine that with HL7 version difference between different HCO's that need to share information about patient registration, admission, discharge, transfers, orders and results for laboratory tests, it does get very complicated rather quickly.

eTransX' HL7 messaging easy implementation solution

eTransX' HL7 messaging solution makes it easier to solve this problem. With a point-and-click data mapping and XML schema based HL7 messages with its guaranteed delivery on the HL7/X12 transactions, it takes the difficulties associated with customized HL7 messaging and version difference out of an HCO. It allows an HCO to implement a full-blown HL7 messaging system out-of-the-box, in a very short time with absolutely no programming. This reduces the cost and improves the information sharing which results in a better patient care for the HCO.

Wednesday, April 23, 2008

An Introduction to Java Annotations

The objective of changing older JDK versions to JDK5 largely centered on enhancing ease-of-development. In other words, the new features shift the responsibility for writing the boilerplate code from the programmer to the compiler. If the source code is boilerplate free, it becomes easier to maintain. The resulting codes are also less likely to be bug-prone. One of these new ease-of-development features in JDK5 are annotations. Annotations are like meta-tags that you can add to your code and apply them to package declarations, type declarations, constructors, methods, fields, parameters, and variables. As a result, you will have helpful ways to indicate whether your methods are dependent on other methods, whether they are incomplete, whether your classes have references to other classes, and so on.

Annotation-based development is certainly one of the latest Java development trends. Annotation-based development relieves Java developers from the pain of cumbersome configuration. Quoting from Sun's official site, "It (annotation-based development) lets us avoid writing boilerplate code under many circumstances by enabling tools to generate it from annotations in the source code. This leads to a declarative programming style where the programmer says what should be done and tools emit the code to do it." Simply speaking, annotation is a mechanism for associating a meta-tag with program elements and allowing the compiler or the VM to extract program behaviors from these annotated elements and generate interdependent codes when necessary. In the first part of this three-article series, I'll describe some basics of annotation, their benefits, as well as some example usages.

The Basics

There are two things you need to consider with annotations. One is the "annotation" itself; another is the "annotation type." An annotation is the meta-tag that you will use in your code to give it some life. Annotation type is used for defining an annotation. You will use it when you want to create your own custom annotation. The type is the actual construct used, and the annotation is the specific usage of that type.

An annotation type definition takes an "at" (@) sign, followed by the interface keyword plus the annotation name. On the other hand, an annotation takes the form of an "at" sign (@), followed by the annotation type. This is simplest form of annotation. Additionally, you can put data within parenthesis after the annotation name. An example of each can be seen below:

Example to Define an Annotation (Annotation type)

public @interface MyAnnotation {
   String doSomething();
}

Example to Annotate Your Code (Annotation)

MyAnnotation (doSomething="What to do")
public void mymethod() {
   ....
}

Annotation Types

There are three annotation types:

· Marker: Marker type annotations have no elements, except the annotation name itself.

Example:

public @interface MyAnnotation {
}

Usage:

@MyAnnotation
public void mymethod() {
   ....
}
  • Single-Element: Single-element, or single-value type, annotations provide a single piece of data only. This can be represented with a data=value pair or, simply with the value (a shortcut syntax) only, within parenthesis.

Example:

public @interface MyAnnotation
{
    String doSomething();
}

Usage:

@MyAnnotation ("What to do")
public void mymethod() {
   ....
}
  • Full-value or multi-value: Full-value type annotations have multiple data members. Therefore, you must use a full data=value parameter syntax for each member.

Example:

public @interface MyAnnotation {
   String doSomething();
   int count; String date();
}

Usage:

@MyAnnotation (doSomething="What to do", count=1,
               date="09-09-2005")
public void mymethod() {
   ....
}

Rules of Thumb for Defining Annotation Type

Here are some rules-of-thumb when defining an annotation type:

  1. Annotation declaration should start with an 'at' sign like @, following with an interface keyword, following with the annotation name.
  2. Method declarations should not have any parameters.
  3. Method declarations should not have any throws clauses.
  4. Return types of the method should be one of the following:
    • primitives
    • String
    • Class
    • enum
    • array of the above types

Annotations

There are two types of annotations available with JDK5:

  • Simple annotations: These are the basic types supplied with Tiger, which you can use to annotate your code only; you cannot use those to create a custom annotation type.
  • Meta annotations: These are the annotation types designed for annotating annotation-type declarations. Simply speaking, these are called the annotations-of-annotations.

Simple Annotations

There are only three types of simple annotations provided by JDK5. They are:

  • Override
  • Deprecated
  • Suppresswarnings

It's important to note that JDK5 (in other words, Tiger) actually does not have many built-in annotations; rather, it allows core Java the ability to support the annotation feature. The charter for JSR-175 strictly dictated it was to define a metadata facility. It was left to the programmers to write custom annotation types and to other JSRs to write a set of standard annotation types. The following sections will describe each simple annotation in more depth, along with examples.

The Override annotation

An override annotation indicates that the annotated method is required to override a method in a super class. If a method with this annotation does not override its super-class's method, the compiler will generate an error. Example 1 demonstrates the override annotation:

Example 1

public class Test_Override {
@Override
public String toString() {
   return super.toString() +
   " Testing annotation name: 'Override'";
}
}

What happens if a spelling mistake occurs with the method name? For example, if you change the name of the toString method to "tostring" and compile the code, you will get something like the following:

Compiling 1 source file to D:tempNew Folder (2)
                              TestJavaApplication1buildclasses
D:tempNew Folder (2)TestJavaApplication1srctest
   myannotationTest_Override.java:24: method does not override
                a method from its superclass
@Override
1 error
BUILD FAILED (total time: 0 seconds)

The Deprecated annotation

This annotation indicates that when a deprecated program element is used, the compiler should warn you about it. Example 2 shows you the deprecated annotation.

Example 2

First, create a class with the deprecated method as follows:

public class Test_Deprecated {
   @Deprecated
   public void doSomething() {
      System.out.println("Testing annotation name: 'Deprecated'");
   }
}

Next, try to invoke this method from another class:

public class TestAnnotations {
   public static void main(String arg[]) throws Exception {
      new TestAnnotations(); 
   }
   public TestAnnotations() {
   Test_Deprecated t2=new Test_Deprecated();
   t2.doSomething();
}

The doSomething() method in this example is declared as a deprecated method. Therefore, this method should not be used when this class is instantiated by other classes. If you compile Test_Deprecated.java, no warning messages will be generated by the compiler. But, if you try to compile TestAnnotations.java where the deprecated method is used, you will see something like this:

Compiling 1 source file to D:tempNew Folder
(2)TestJavaApplication1buildclasses
D:tempNew Folder
(2)TestJavaApplication1srctestmyannotation
    TestAnnotations.java:27:
warning: [deprecation] doSomething() in
test.myannotation.Test_Deprecated has been deprecated
t2.doSomething();
1 warning

The Suppresswarnings annotation

This annotation indicates that compiler warnings should be shielded in the annotated element and all of its sub-elements. The set of warnings suppressed in an element is the superset of the warnings in all of its containing sub-elements. As an example, if you annotate a class to suppress one warning and one of its methods to suppress another warning, both warnings will be suppressed at the method level only. See Example 3 for the suppresswarnings annotation.

Example 3

public class TestAnnotations {
   public static void main(String arg[]) throws Exception {
      new TestAnnotations().doSomeTestNow();
   }
   @SuppressWarnings({"deprecation"})
   public void doSomeTestNow() {
      Test_Deprecated t2 = new Test_Deprecated();
      t2.doSomething();
   }
}

In this example, you are suppressing the deprecation warning for the method listing shown in Example 2. Because the method is suppressed, you are unlikely to view the "deprecation" warning any more.

Note: It is a good idea to use this annotation at the most deeply nested element where it is effective. Therefore, if you want to suppress a warning in a particular method, you should annotate that method rather than its class.

Meta-Annotations (Annotation Types)

Meta-annotations, which are actually known as the annotations of annotations, contain four types. These are:

  • Target
  • Retention
  • Documented
  • Inherited

The Target annotation

The target annotation indicates the targeted elements of a class in which the annotation type will be applicable. It contains the following enumerated types as its value:

  • @Target(ElementType.TYPE)—can be applied to any element of a class
  • @Target(ElementType.FIELD)—can be applied to a field or property
  • @Target(ElementType.METHOD)—can be applied to a method level annotation
  • @Target(ElementType.PARAMETER)—can be applied to the parameters of a method
  • @Target(ElementType.CONSTRUCTOR)—can be applied to constructors
  • @Target(ElementType.LOCAL_VARIABLE)—can be applied to local variables
  • @Target(ElementType.ANNOTATION_TYPE)—indicates that the declared type itself is an annotation type

Example 4 demonstrates the target annotation:

Example 4

First, define an annotation named Test_Target with @Target metadata, as follows:

@Target(ElementType.METHOD)
public @interface Test_Target {
   public String doTestTarget();
}

Next, create a class that will use the Test_Target annotation:

public class TestAnnotations {
   public static void main(String arg[]) {
      new TestAnnotations().doTestTarget();
   }
   @Test_Target(doTestTarget="Hello World !")
   public void doTestTarget() {
      System.out.printf("Testing Target annotation");
   }
}

The @Target(ElementType.METHOD) indicates that this annotation type can be used to annotate only at the method levels. If you compile the preceding code, no warning messages will be shown. Now, if you declare a String variable and apply your newly created annotation, what will happen? Let me demonstrate this as follows:

public class TestAnnotations {
   @Test_Target(doTestTarget="Hello World !")
   private String str;
   public static void main(String arg[]) {
      new TestAnnotations().doTestTarget();
   }
   public void doTestTarget() {
      System.out.printf("Testing Target annotation");
   }
}

The only change you can see from above is that the annotation declaration is shifted from method-level to field-level, which is not correct. Because you have defined your annotation @Test_Target to be applicable only at method-level, if you try to compile this class, you are likely to get something like this:

"TestAnnotations.java": 
D:R_AND_DTestAnnotationsrctestmyannotation
   TestAnnotations.java:16: 
annotation type not applicable to this kind of declaration at line
16, column 0
@Test_Target(doTestTarget="Hello World !")
^
Error in javac compilation

The Retention annotation

The retention annotation indicates where and how long annotations with this type are to be retained. There are three values:

  • RetentionPolicy.SOURCE—Annotations with this type will be by retained only at the source level and will be ignored by the compiler
  • RetentionPolicy.CLASS—Annotations with this type will be by retained by the compiler at compile time, but will be ignored by the VM
  • RetentionPolicy.RUNTIME—Annotations with this type will be retained by the VM so they can be read only at run-time

Example 5 shows you the RetentionPolicy.RUNTIME value in action:

Example 5

@Retention(RetentionPolicy.RUNTIME)
public @interface Test_Retention {
   String doTestRetention();
}

In this example, the @Retention(RetentionPolicy.RUNTIME) annotation indicates that your Test_Retention annotation is to be retained by the VM so that it can be read reflectively at run-time.

The Documented annotation

The documented annotation indicates that an annotation with this type should be documented by the javadoc tool. By default, annotations are not included in javadoc. But if @Documented is used, it then will be processed by javadoc-like tools and the annotation type information will also be included in the generated document. Example 6 demonstrates using @Documented further:

Example 6

@Documented
public @interface Test_Documented {
   String doTestDocument();
}

Next, update your TestAnnotations class as follows:

public class TestAnnotations {
   public static void main(String arg[]) {
      new TestAnnotations().doSomeTestRetention();
      new TestAnnotations().doSomeTestDocumented();
   }
   @Test_Retention (doTestRetention="Hello retention test")
   public void doSomeTestRetention() {
      System.out.printf("Testing annotation 'Retention'");
   }
   @Test_Documented(doTestDocument="Hello document")
   public void doSomeTestDocumented() {
      System.out.printf("Testing annotation 'Documented'");
   }
}

Now, if you run the javadoc command and view the generated TestAnnotations.html file, you will see something like Figure 1.

Figure 1

As you can see from the screenshot, there is no annotation-type information for the doSomeTestRetention() method. But, this description is provided for the doSomeTestDocumented() method. This is because of the @Documented tag attached with your Test_Documented annotation. Your earlier annotation Test_Retention did not include this tag.

The Inherited annotation

This is a bit of a complex annotation type. It indicates that the annotated class with this type is automatically inherited. More specifically, if you define an annotation with the @Inherited tag, then annotate a class with your annotation, and finally extend the class in a subclass, all properties of the parent class will be inherited into its subclass. With Example 7, you will get an idea about the benefits of using the @Inherited tag.

Example 7

First, define your annotation:

@Inherited
   public @interface myParentObject { 
      boolean isInherited() default true;
      String doSomething() default "Do what?";
   }

Next, annotate a class with your annotation:

@myParentObject
public Class myChildObject {
   }

As you can see, you do not have to define the interface methods inside the implementing class. These are automatically inherited because of using the @Inherited tag. What would happen if you define the implementing class in old-fashioned Java-style? Take a look at this—defining the implementation class in an old-style-java way:

public class myChildObject implements myParentObject {
   public boolean isInherited() {
      return false;
   }
   public String doSomething() {
      return "";
   }
   public boolean equals(Object obj) {
      return false;
   }
   public int hashCode() {
      return 0;
   }
   public String toString() {
      return "";
   }
   public Class annotationType() {
      return null;
   }
}

Do you see the difference? You can see that you will have to implement all the methods that the parent interface owns. Besides the isInherited() and doSomething() methods from myParentObject, you will have to implement the equals(), toString(), and hasCode() methods of java.lang.Object and also the annotationType() method of java.lang.annotation.Annotation class. It does not matter whether you want to implement these methods or not; you will have to include these in your inherited object.

Conclusion

This article has shown you how you can make your development easier through the use of JDK5's annotation feature. Annotations do not directly affect the semantics of a program. Development and deployment tools can read these annotations and process them in some fashion, perhaps producing additional Java programming language source files, XML documents, or other artifacts to be used in conjunction with the program containing the annotations. You now can do the same things as you would do before, but with less code and better compile-time error detection. The objective is to spend less time on unhandy code-writing and focus more on business logic rules. This article is Part I of a series on Java Annotations. In Part II, you will learn about how to use annotations to develop a simple Web application with a flat table. Lastly, in Part III you will see a complex example that includes multiple database tables relationships.

Resources

  1. J2SE 5.0 in a Nutshell at http://java.sun.com/developer/technicalArticles/releases/j2se15/
  2. Annotations in Tiger, Part 1: Add metadata to Java code at http://www-128.ibm.com/developerworks/java/library/j-annotate1/
  3. What's New in Java 1.5? at http://www.cs.indiana.edu/classes/jett/sstamm/

Tuesday, April 15, 2008

TESTING

Test Harness testing

Monday, April 14, 2008

JAVA MAIL

JAVAMAIL API

General

  1. What is the JavaMail API?
  2. How do I get an implementation of the JavaMail API?
  3. How do I send feedback or comments?
  4. Where is javax.activation?
  5. What JDK does the JavaMail API need?
  6. Where can I find a version of JavaMail for my favorite operating system?
  7. Do the JavaMail APIs work in web browsers?
  8. Can I use JavaMail to read mail from my web mail account (such as Yahoo or Hotmail)?
  9. What is IMAP?
  10. What is SMTP?
  11. What is MIME?
  12. What is POP3?
  13. What about support for MAPI, NNTP, Lotus Notes, and other service providers?
  14. How do I store mail messages on my local disk?
  15. Where do I find documentation on the Sun protocol providers?
  16. Is the JavaMail API implementation completely free? Can I ship it along with my product?
  17. Can I get the source code for the JavaMail API implementation? [updated!]
  18. Is JavaMail Y2K compliant?
  19. The answer to my question isn't here, where else should I look?
  20. Installation and Configuration
  21. How do I install the JavaMail API implementation?
  22. Does JavaMail include all the necessary mail servers?
  23. Where can I get the necessary mail servers? [updated!]
  24. What host name, user name, or password should I use?
  25. How do I configure JavaMail to work through my proxy server?
  26. When connecting to my mail server over SSL I get an exception like "unable to find valid certification path to requested target". [new!]
  27. How do I set my CLASSPATH on Windows NT?
  28. While trying to run my program on Linux I get a very strange error message and the program fails. What did I do wrong?
  29. How do I use JavaMail in an application run under a SecurityManager; what permissions must I grant to the application and to JavaMail? [updated!]
  30. How do I configure my web server to run the JavaMail demo servlet?
  31. When using JavaMail in my servlet, it is unable to find any of the JavaMail classes. I've added mail.jar to the server's CLASSPATH.
  32. I'm sure I've set my CLASSPATH correctly, but I'm still getting complaints about classes that can't be found, such as com.sun.mail classes. [new!]
  33. My servlet can find the JavaMail classes, but JavaMail complains that it can't find a service provider for "smtp" or "imap" or address type "rfc822".
  34. How do I access Gmail with JavaMail? [new!]
  35. How do I access Yahoo! Mail with JavaMail? [new!]
  36. Programming
  37. Where can I learn the basics about Internet email that I'll need to know to program JavaMail effectively?
  38. Where can I find some example programs that show how to use JavaMail?
  39. How do I send a message with an attachment?
  40. How do I read a message with an attachment and save the attachment? [updated!]
  41. How do I tell if a message has attachments?
  42. How do I find the main message body in a message that has attachments? [new!]
  43. Should I use the isMimeType method, or should I use instanceof on the object returned by the getContent method, when deciding how to process a message part? [new!]
  44. When I attach a file it gets a MIME type of application/octet-stream instead of the correct MIME type. [new!]
  45. How do I manually set the MIME type for an attached file, for example in the case where the filename doesn't have an obvious extension? [new!]
  46. How do I create a multipart message with a part of any MIME type I choose?
  47. What is "disconnected support"?
  48. How do I support disconnected operation using the JavaMail APIs?
  49. How do I send secure email using the JavaMail APIs?
  50. The writeTo() method generates message text with lines that are neither the canonical MIME representation of the data (i.e., using CRLF to terminate lines), nor using the canonical line separator of my platform (e.g., "\n" on UNIX). How do I get either of these representations if I need them?
  51. Can I use the JavaMail APIs to implement a mail server?
  52. Can I use the JavaMail APIs to add new user accounts to my mail server, remove user accounts from my mail server, or change the passwords for user accounts on my mail server?
  53. Can I use the JavaMail APIs to access my address book on my mail server? [new!]
  54. Why doesn't the MimeMessage class implement Serializable so that I can serialize a message to disk and read it back later?
  55. How do I write a Service Provider?
  56. I'm having trouble logging into my Microsoft Exchange server, even though I'm sure I'm using the correct username and password, what could I be doing wrong?
  57. How do I encode a binary file before sending it and how do I decode it when I receive it?
  58. If I don't need to encode and decode attachments myself, when should I use the MimeUtility methods?
  59. I have data that's already encoded in (e.g.) base64, how do I tell JavaMail to send this data without re-encoding it?
  60. Even though JavaMail does all the encoding and decoding for me, I need to manually control the encoding for some body parts.
  61. Why doesn't JavaMail properly encode and decode filenames in non-ASCII character sets?
  62. Debugging
  63. How do I debug my application that uses JavaMail APIs?
  64. How do I debug problems connecting to my mail server?
  65. How do I debug problems connecting to my mail server using SSL?
  66. How do I debug problems with Java security permissions? [new!]
  67. Reading mail, IMAP
  68. I tried running your demos against my IMAP server, but I get an error.
  69. I can read messages from my IMAP server with other mail clients, but even though I can connect to the server using JavaMail, when I use JavaMail to read some messages it fails. Doesn't that mean there's a bug in JavaMail? [new!]
  70. The IMAP provider seems to lose data when I fetch messages with large attachments.
  71. Does the IMAP provider cache the retrieved data?
  72. I want to move messages between folders. Should I use appendMessages() or copyMessages()?
  73. Retrieving large message bodies seems inefficient at times.
  74. I get OutOfMemory errors when loading this large binary attachement.
  75. Why do I get the UnsupportedDataTypeException when I invoke getContent() on a bodypart?
  76. Why do I get the UnsupportedEncodingException when I invoke getContent() on a bodypart that contains text data?
  77. Sending mail, SMTP
  78. How do I reply to a message?
  79. How do I forward a message?
  80. How do I send HTML mail?
  81. How do I send mail with formatted text using different fonts and colors?
  82. How do I send mail with both plain text as well as HTML text so that each mail reader can choose the format appropriate for it?
  83. How do I send HTML mail that includes images?
  84. What's the difference between the Transport methods send and sendMessage?
  85. When I try to send a message I get an error like SMTPSendFailedException: 530, Address requires authentication. [updated!]
  86. I need to authenticate to my SMTP server so I call trans.connect(host, user, password) and then trans.send(msg) to send the message, but it's not working.
  87. I modified this message, but the headers do not reflect the changes.
  88. I set a particular value for the Message-ID header of my new message, but when I send this message that header is rewritten.
  89. Why do I get an UnsupportedDataTypeException when sending this new message that I created?
  90. How can I explicitly set the SMTP FROM: attribute when sending a message?
  91. I want to repeatedly send messages, to a different set of recipients each time. But invoking Transport.send(Message) causes a new Transport session to be established each time. This is suboptimal in this case, so how do I get around this?
  92. I get "MessagingException: 501 HELO requires domain address" when trying to send a message.
  93. If I send a message to a bad address, why don't I get a SendFailedException or TransportEvent indicating that the address is bad?
  94. When a message can't be delivered, a failure message is returned. How can I detect these "bounced" messages?
  95. When I construct an InternetAddress object, why don't I get an exception if the address is illegal?
  96. When I try to send a message, why do I get javax.mail.SendFailedException: 550 Unable to relay for my-address?
  97. When I try to send a message to (for example) Yahoo, why do I get an error that says "connection refused"?
  98. When sending mail, why does it fail with an exception that includes a message something like 553 To send mail, first check your mail with a valid POP account?
  99. POP3
  100. I want to delete messages on a POP3 server. I set the DELETED flag on those messages. Then I call the expunge() method, but I get a MethodNotSupportedException. How do I delete messages when I use Sun's POP3 provider?
  101. How can I retrieve POP3 UIDLs in messages obtained from Sun's POP3 provider?
  102. How can I tell which messages are new with POP3?
  103. Why does hasNewMessages() always return false when using POP3?
  104. I set up a MessageCountListener (as demonstrated in the monitor program) but I'm never notified of new mail in my POP3 INBOX.
  105. Why does getReceivedDate() return null when using POP3?
  106. When using POP3 I get complaints about the SocketFetcher class.
  107. When using POP3 I get complaints about the contentStream field.
  108. How do I access or create folders other than INBOX on my POP3 server?
  109. Why does the getSize method return a negative number when using POP3?
  110. I'm having problems using POP3 with Microsoft Exchange.
  111. JavaMail in servlets
  112. Can I use JavaMail in servlets?
  113. My web application uses JavaMail to attach and send a file that the user specifies, but my application can't find the file.
  114. JavaMail in applets
  115. Can I use JavaMail in applets?
  116. What are the security implications of using JavaMail in an applet?
  117. Ok, maybe I really don't want to use an applet, what should I do instead?

General

Q: What is the JavaMail API?
A: The JavaMail API is a set of abstract APIs that model a mail system. The API provides a platform independent and protocol independent framework to build Java technology based email client applications. The JavaMail API provides facilities for reading and sending email. Service providers implement particular protocols. Several service providers are included with the JavaMail API package; others are available separately. The JavaMail API is implemented as a Java optional package that can be used on JDK 1.4 and later on any operating system. The JavaMail API is also a required part of the Java Platform, Enterprise Edition (Java EE).

Q: How do I get an implementation of the JavaMail API?
A: Sun provides a royalty-free reference implementation, in binary form, that developers may use and ship. The reference implementation includes the core JavaMail packages and IMAP, POP3, and SMTP service providers. The reference implementation may be downloaded here.

Q: How do I send feedback or comments?
A: Send email to javamail@Sun.COM. Also consider joining our low-volume announce mailing list javamail-announce@java.sun.com. Instructions on how to join are in our web page at http://java.sun.com/products/javamail

Q: Where is javax.activation?
A: javax.activation is part of the JavaBeans Activation Framework (JAF). The JAF is part of the JavaBeans "Glasgow" specification (see http://java.sun.com/beans/glasgow/jaf.html). The JavaMail API uses the JAF for data content handling.

Q: What JDK does the JavaMail API need?
A: The JavaMail API requires JDK/JRE 1.4 or higher. The JavaMail API is a Java optional package, it is not part of the core Java SE but is included in Java EE.

Q: Where can I find a version of JavaMail for my favorite operating system?
A: JavaMail is completely written in Java and will run on any operating system that supports the required version of the JDK. No special version is needed for different operating systems.

Q: Do the JavaMail APIs work in web browsers?
A: JavaMail will work in any browser that supports the required JDK version. The Java Plug-in may be required to provide such support.

Q: Can I use JavaMail to read mail from my web mail account (such as Yahoo or Hotmail)?
A: It depends. Many web-based email services provide access only using a browser with HTTP. These services cannot be accessed using JavaMail. If the service also provides POP3 or IMAP access, JavaMail can probably be used to access it. Contact your web email service provider for details. Also, see the JHTTPMail project for an open source provider for JavaMail that provides access to Hotmail. Another helpful tool is MrPostman, a proxy server that provides POP3 access to Hotmail and Yahoo! Mail, available at http://mrbook.org/mrpostman/

Q: What is IMAP?
A: IMAP stands for Internet Message Access Protocol. It is a method of accessing electronic mail messages stored on a (possibly shared) mail server. In other words, it permits a "client" email program to access remote message stores as if they were local. IMAP is defined by RFC2060. For more information, see http://www.imap.org/

Q: What is SMTP?
A: SMTP stands for Simple Mail Transfer Protocol. It is used to transfer RFC822-style messages between different mail hosts as well as to submit new messages to a host for delivery. SMTP is in very wide use (it originated in 1982) and is defined by RFC821.

Q: What is MIME?
A: MIME and RFC822 are the standards for describing email messages that are sent across the Internet. The javax.mail.internet subpackage (which is part of the JavaMail APIs) provides a complete implementation of these two packages. MIME is specified by the following RFCs: RFC2045, RFC2046, RFC2047.

Q: What is POP3?
A: POP3 stands for Post Office Protocol version 3. POP3 is a very limited protocol for accessing a single mailbox. It is much less capable than IMAP. POP3 is very widely used and is defined by RFC1939.

Q: What about support for MAPI, NNTP, Lotus Notes, and other service providers?
A: We have no current plans to implement any of these providers. However, the architecture of the JavaMail APIs provides for being able to easily plug-in third-party service providers. It is our hope that third-parties will embrace the JavaMail APIs by writing providers for other standard and proprietary protocols. See our Third Party Products page for the latest list of such providers.

Q: How do I store mail messages on my local disk?
A: A "local store provider" can be used to store mail messages on a local disk. The JavaMail APIs do not include such a provider but several are available from third parties for different local store formats such as MH and Mbox. See our Third Party Products page for the latest list of such providers.

Q: Where do I find documentation on the Sun protocol providers?
A: The Sun protocol providers for IMAP, POP3, and SMTP support many features that are not part of the JavaMail API specification. The documentation for these protocol providers is included in the JavaMail javadocs. The package level documentation for each protocol provider package describes the properties that are supported by the protocol proivder. In addition, the protocol providers include some classes and methods that applications can use to take advantage of provider-specific features. Note that use of these properties, classes, and methods renders a program non-portable; it may only work with Sun's implementation of the JavaMail API. See the IMAP, POP3, and SMTP package javadocs for details.

Q: Is the JavaMail API implementation completely free? Can I ship it along with my product?
A: Yes. The current release of the JavaMail API implementation, is completely free and you can include it in your product. This release includes IMAP, POP3, and SMTP providers as well. Please do read the license and ensure that you understand it. (The license is available after clicking the Download button on the download page.) The JavaBeans Activation Framework is also free for use under a similar license.

Q: Can I get the source code for the JavaMail API implementation? [updated!]
A: Starting with JavaMail 1.4, the source code for the JavaMail API Reference Implementation is available under the CDDL open source license as part of Project GlassFish. See the mail module page at GlassFish for more details.

Q: Is JavaMail Y2K compliant?
A: Yes. Sun's JavaMail implementation is Option-3 Y2K compliant. Please see the NOTES.txt file in the JavaMail package for more information.

Q: The answer to my question isn't here, where else should I look?
A: In addition to the JavaMail API spec and javadocs (available both from our main web page and included in the download bundle), don't forget to check the README.txt and NOTES.txt files included with the JavaMail API package for additional important information.

The javamail-interest mailing list is another source of information. See our main web page for instructions on how to subscribe and a pointer to the archives.

You can reach the JavaMail team directly at javamail@sun.com. You can use this address to report bugs. Bugs can also be reported at http://bugs.sun.com.

The Sun Developer Network maintains a JavaMail forum, see the JavaMail Forum. As you might expect, the JavaMail team strongly prefers that you use email to submit questions to one of the addresses above.

jGuru also maintains a JavaMail FAQ, which you'll find at http://www.jguru.com/faq/JavaMail.

Installation and Configuration

Q: How do I install the JavaMail API implementation?
A: Unzip the distribution zip file and edit your CLASSPATH environment variable to include the mail.jar file that was included with the JavaMail API distribution. You will also need an implementation of the JavaBeans Activation Framework (see below). See the README.txt file (also included in the download package) for additional details and examples.

Q: Does JavaMail include all the necessary mail servers?
A: No, the JavaMail API package does not include any mail servers. To use the JavaMail API package, you'll need to have access to an IMAP or POP3 mail server (for reading mail) and/or an SMTP mail server (for sending mail). These mail servers are usually provided by your Internet Service Provider or are a part of your organization's networking infrastructure. If you don't have access to such a mail server, see below.

Q: Where can I get the necessary mail servers? [updated!]
A: Sun Java System Messaging Server is available for Solaris and Windows platforms. The University of Washington IMAP server supports multiple platforms (UNIX, Windows 32bit, etc). Get the source code from ftp://ftp.cac.washington.edu/imap/imap.tar.Z. There are several free, all Java mail servers available, including Apache James and Java Email Server. Sendmail is a popular (non-Java) SMTP server. SubEthaSMTP is a Java library for implementing SMTP server functionality; their web page also references other mail servers. Many other vendors provide mail servers supporting Internet standards. More information can be obtained from The IMAP Connection and the Internet Mail Consortium.

Q: What host name, user name, or password should I use?
A: We do not provide a mail server for you to use. You must use your own mail server, or one provided by your Internet Service Provider or the company you work for. Your network administrator can give you the information necessary to configure JavaMail to work with your mail server.

Q: How do I configure JavaMail to work through my proxy server?
A: JavaMail does not currently support accessing mail servers through a web proxy server. One of the major reasons for using a proxy server is to allow HTTP requests from within a corporate network to pass through a corporate firewall. The firewall will typically block most access to the Internet, but will allow requests from the proxy server to pass through. In addition, a mail server inside the corporate network will perform a similar function for email, accepting messages via SMTP and forwarding them to their ultimate destination on the Internet, and accepting incoming messages and sending them to the appropriate internal mail server.

If your proxy server supports the SOCKS V4 or V5 protocol (http://www.socks.nec.com/aboutsocks.html, RFC1928) and allows anonymous connections, you can tell the Java runtime to direct all TCP socket connections to the SOCKS server. See the Networking Properties guide for the latest documentation of the socksProxyHost and socksProxyPort properties. These are system-level properties, not JavaMail session properties. They can be set from the command line when the application is invoked, for example: java -DsocksProxyHost=myproxy .... This facility can be used to direct the SMTP, IMAP, and POP3 communication from JavaMail to the SOCKS proxy server. Note that setting these properties directs all TCP sockets to the SOCKS proxy, which may have negative impact on other aspects of your application.

Without such a SOCKS server, if you want to use JavaMail to directly access mail servers outside the firewall, the firewall will need to be configured to allow such access. JavaMail does not support access through a HTTP proxy web server.

Q: When connecting to my mail server over SSL I get an exception like "unable to find valid certification path to requested target". [new!]
A: Your server is probably using a test certificate or self-signed certificate instead of a certificate signed by a commercial Certificate Authority. You'll need to install the server's certificate into your trust store. The InstallCert program will help.

Q: How do I set my CLASSPATH on Windows NT?
A: Detailed instructions are available here

Q: While trying to run my program on Linux I get a very strange error message and the program fails. What did I do wrong?
A: The error message often looks something like this:

Exception in thread "main"

java.lang.VerifyError:(Class:com/sun/mail/pop3/POP3Store,

method: finalize Signature :()V)

Illegal use of nonvirtual function call

The problem is due to a buggy version of the unzip command used to unzip the JavaMail download package on Linux. The unzip command corrupts the mail.jar file. Get a newer version of the unzip command, or use the JDK's jar command to unzip the package.

Q: How do I use JavaMail in an application run under a SecurityManager; what permissions must I grant to the application and to JavaMail? [updated!]
A: When using JavaMail in an environment with a SecurityManager, JavaMail will sometimes fail to read the configuration files in the mail.jar file. The JavaBeans Activation Framework may have the same problem reading configuration files from the activation.jar file. These default configuration files are stored as "resource" files in the META-INF directory in the jar file.

There are a number of debugging techniques that can be used to determine if this is the problem. Setting the Session property "mail.debug" to true (or calling session.setDebug(true)) will cause JavaMail to print debugging messages as it attempts to load each configuration file. A message of the form "DEBUG: can't load default providers file" indicates that this problem might exist. Similarly, setting the System property "javax.activation.debug" to "true" (e.g., by running the program using "java -Djavax.activation.debug=true ...") will cause JAF to print debugging messages as it attempts to load each resource file. Finally, the JDK can produce helpful debugging output by setting the system property "java.security.debug" to "access:failure" (e.g., by running the program using "java -Djava.security.debug=access:failure ..."). The command java -Djava.security.debug=help will display other security debugging options.

In addition to the permissions necessary to read the configuration files, the application (and JavaMail) will also need permission to connect to the mail servers it uses. If the application uses System properties to configure JavaMail (e.g., by passing the Properties object returned from System.getProperties() to the Session constructor, as many of the JavaMail demo programs do), it will also need permission to use the System Properties object. Alternatively, the application can use its own Properties object and be sure to set the "mail.from" property or the "mail.user" and "mail.host" properties (see the InternetAddress.getLocalAddress() method).

To allow an application to use JavaMail under a SecurityManager, the application, JavaMail, and JAF will need permissions such as the following (be sure to replace the host and path names with appropriate values); add these to the security policy file used by the application:

grant {

// following two permissions allow

// access to default config files

permission java.io.FilePermission

"/path/to/mail.jar", "read";

permission java.io.FilePermission

"/path/to/activation.jar", "read";

// following to use SMTP

permission java.net.SocketPermission

"SMTPHOST:25", "connect,resolve";

// following to use IMAP

permission java.net.SocketPermission

"IMAPHOST:143", "connect,resolve";

// following to use POP3

permission java.net.SocketPermission

"POP3HOST:110", "connect,resolve";

// following needed if System.getProperties() is used

permission java.util.PropertyPermission

"*", "read,write";

};



If you don't want to give the application read/write permission to System properties, but you still want to be able to use System properties to configure the application, you can give the application only "read" permission to System properties and use the following approach:

Properties props = (Properties)System.getProperties().clone();

props.put("mail.smtp.host", "whatever");

// set as properties as needed

Session session = Session.getInstance(props, null);



Q: How do I configure my web server to run the JavaMail demo servlet?
A: Instructions for the following web servers are available here:

Tomcat

Apache with JServ

Sun Java System Web Server

Q: When using JavaMail in my servlet, it is unable to find any of the JavaMail classes. I've added mail.jar to the server's CLASSPATH.
A: It is often necessary to completely restart the web server when changing the CLASSPATH.

Q: I'm sure I've set my CLASSPATH correctly, but I'm still getting complaints about classes that can't be found, such as com.sun.mail classes. [new!]
A: The most common cause of problems like this is having more than one copy of mail.jar in your CLASSPATH or available to your application. In addition to checking your CLASSPATH setting, also look for copies in the jre/lib/ext directory of your JDK installation. If you're running in a web server or application server, it may be providing its own version of mail.jar in one of its directories. You should only have one version of mail.jar available to your application.

Q: My servlet can find the JavaMail classes, but JavaMail complains that it can't find a service provider for "smtp" or "imap" or address type "rfc822".
A: Usually this is because JavaMail can't access the configuration files in mail.jar, possibly because of a security permission problem; see this item for more details. Also, make sure that you haven't extracted the mail.jar contents; you should include the unmodified mail.jar file in the server's CLASSPATH.

Q: How do I access Gmail with JavaMail? [new!]
A: JavaMail 1.4 is capable of sending and reading messages using Gmail. All that's required is to properly configure JavaMail. I'll illustrate the proper configuration using the demo programs that come with JavaMail - msgshow.java and smtpsend.java.

Let's assume your Gmail username is "user@gmail.com" and your password is "passwd".

To read mail from your Gmail Inbox, invoke msgshow as follows:

java msgshow -D -T pop3s -H pop.gmail.com -U user -P passwd

By reading the msgshow.java source code, you can see how these command line arguments are used in the JavaMail API. You should first try using msgshow as shown above, and once that's working move on to writing and configuring your own program to use Gmail.

To send a message through Gmail, invoke smtpsend as follows:

java -Dmail.smtps.host=smtp.gmail.com -Dmail.smtps.auth=true

smtpsend -d -S -M smtp.gmail.com -U user -P passwd -A user@gmail.com

(Note that I split the command over two lines for display, but you should type it on one line.)

A bug in older versions of the smtpsend command causes it to set the incorrect properties when using the -S (SSL) option, so we work around that bug by setting them on the command line. The smtpsend program uses the System properties when creating the JavaMail Session, so the properties set on the command line will be available to the JavaMail Session.

The smtpsend program will prompt for a subject and message body text. End the message body with ^D on UNIX or ^Z on Windows.

Again, you can read the smtpsend.java source code to see how the command line arguments are used in the JavaMail API. There is, of course, more than one way to use the JavaMail API to accomplish the same goal. This should help you understand the essential configuration parameters necessary to use Gmail.

Q: How do I access Yahoo! Mail with JavaMail? [new!]
A: JavaMail 1.4 is capable of sending and reading messages using Yahoo! Mail Plus. All that's required is to properly configure JavaMail. I'll illustrate the proper configuration using the demo programs that come with JavaMail - msgshow.java and smtpsend.java.

Note that free Yahoo! Mail accounts do not allow POP3 or SMTP access. You must purchase a Yahoo! Mail Plus account to get POP3 and SMTP access.

Let's assume your Yahoo! Mail username is "user@yahoo.com" and your password is "passwd".

To read mail from your Yahoo! Mail Inbox, invoke msgshow as follows:

java msgshow -D -T pop3s -H pop.mail.yahoo.com -U user -P passwd

By reading the msgshow.java source code, you can see how these command line arguments are used in the JavaMail API. You should first try using msgshow as shown above, and once that's working move on to writing and configuring your own program to use Yahoo! Mail.

To send a message through Yahoo! Mail, invoke smtpsend as follows:

java -Dmail.smtps.host=smtp.mail.yahoo.com -Dmail.smtps.auth=true

smtpsend -d -S -M smtp.mail.yahoo.com -U user -P passwd -A user@yahoo.com

(Note that I split the command over two lines for display, but you should type it on one line.)

A bug in older versions of the smtpsend command causes it to set the incorrect properties when using the -S (SSL) option, so we work around that bug by setting them on the command line. The smtpsend program uses the System properties when creating the JavaMail Session, so the properties set on the command line will be available to the JavaMail Session.

The smtpsend program will prompt for a subject and message body text. End the message body with ^D on UNIX or ^Z on Windows.

Again, you can read the smtpsend.java source code to see how the command line arguments are used in the JavaMail API. There is, of course, more than one way to use the JavaMail API to accomplish the same goal. This should help you understand the essential configuration parameters necessary to use Yahoo! Mail.

Also see the Yahoo! Mail help page Accessing Yahoo! Mail via POP

Programming

Q: Where can I learn the basics about Internet email that I'll need to know to program JavaMail effectively?
A: See one of the books referenced on our web page for a good background on Internet email, MIME, SMTP, IMAP, POP3, etc.

Q: Where can I find some example programs that show how to use JavaMail?
A: There are many example programs included in the JavaMail download package, including simple command line programs illustrating various aspects of the JavaMail API, a Swing-based GUI application, a simple servlet-based application, and a complete web application using JSP pages and a tag library.

Q: How do I send a message with an attachment?
A: A message with attachments is represented as a MIME multipart message where the first part is the main body of the message and the other parts are the attachments. There are numerous examples showing how to construct such a message in the demo programs included in the JavaMail download package. To attach a file use the attachFile method of MimeBodyPart.

Q: How do I read a message with an attachment and save the attachment? [updated!]
A: As described above, a message with an attachment is represented in MIME as a multipart message. In the simple case, the results of the Message object's getContent method will be a MimeMultipart object. The first body part of the multipart object wil be the main text of the message. The other body parts will be attachments. The msgshow.java demo program shows how to traverse all the multipart objects in a message and extract the data of each of the body parts. The getDisposition method will give you a hint as to whether the body part should be displayed inline or should be considered an attachment (but note that not all mailers provide this information). So to save the contents of a body part in a file, use the saveFile method of MimeBodyPart.

To save the data in a body part into a file (for example), use the getInputStream method to access the attachment content and copy the data to a FileOutputStream. Note that when copying the data you can not use the available method to determine how much data is in the attachment. Instead, you must read the data until EOF. The saveFile method of MimeBodyPart will do this for you. However, you should not use the results of the getFileName method directly to name the file to be saved; doing so could cause you to overwrite files unintentionally, including system files.

Note that there are also more complicated cases to be handled as well. For example, some mailers send the main body as both plain text and html. This will typically appear as a multipart/alternative content (and a MimeMultipart object) in place of a simple text body part. Also, messages that are digitally signed or encrypted are even more complex. Handling all these cases can be challenging. Please refer to the various MIME specifications and other resources listed on our main page.

Q: How do I tell if a message has attachments?
A: In the simplest case, a message of MIME type multipart/mixed with more than one body part is likely a message with attachments. As described above, there are more complex cases to consider as well. In particular, messages may have arbitrary nesting of multipart/mixed and multipart/alternative parts and may include multipart/related parts for embedded HTML and multipart/signed and/or multipart/encrypted parts for secure messages. It's up to you to decide how many of these cases you want to handle in your application before deciding that a message has an attachment. Most applications take a very simple approach to this and handle only a few of the most commonly seen cases.

Q: How do I find the main message body in a message that has attachments? [new!]
A: The following approach will handle the most common cases. Handling inproperly formatted messages, message with unknown charsets, signed or encryped messages, can make this much more complex.

private boolean textIsHtml = false;

/**

* Return the primary text content of the message.

*/

private String getText(Part p) throws

MessagingException, IOException {

if (p.isMimeType("text/*")) {

String s = (String)p.getContent();

textIsHtml = p.isMimeType("text/html");

return s;

}

if (p.isMimeType("multipart/alternative")) {

// prefer html text over plain text

Multipart mp = (Multipart)p.getContent();

String text = null;

for (int i = 0; i <>

Part bp = mp.getBodyPart(i);

if (bp.isMimeType("text/plain")) {

if (text == null)

text = getText(bp);

continue;

} else if (bp.isMimeType("text/html")) {

String s = getText(bp);

if (s != null)

return s;

} else {

return getText(bp);

}

}

return text;

} else if (p.isMimeType("multipart/*")) {

Multipart mp = (Multipart)p.getContent();

for (int i = 0; i <>

String s = getText(mp.getBodyPart(i));

if (s != null)

return s;

}

}

return null;

}



You can call the getText method with a Message object (which is a Part).

Q: Should I use the isMimeType method, or should I use instanceof on the object returned by the getContent method, when deciding how to process a message part? [new!]
A: It is almost always more efficient to use the isMimeType method. The msgshow.java demo program shows how to use the isMimeType method when traversing the parts of a message.

Q: When I attach a file it gets a MIME type of application/octet-stream instead of the correct MIME type. [new!]
A: The FileDataSource class uses the JavaBeans Activation Framework (JAF) class MimetypesFileTypeMap to determine the MIME type of a file based on the extension of the filename. The default mapping knows about only a few extensions. You can add support for more extensions either programmatically or by adding a META-INF/mime.types configuration file to your application. For example, to map the .doc extension to the MIME type application/msword, create a META-INF/mime.types file with the single line:

application/msword doc



See the javadocs for the MimetypesFileTypeMap class for details.

Q: How do I manually set the MIME type for an attached file, for example in the case where the filename doesn't have an obvious extension? [new!]
A: Subclass the FileDataSource class and override the getContentType method. (Note that with this approach you can't use the attachFile method.)

File file = new File("filename");

DataSource ds = new FileDataSource(file) {

public String getContentType() {

return "mytype/mysubtype";

}

};

MimeBodyPart mbp = new MimeBodyPart();

mbp.setDataHandler(new DataHandler(ds));

mbp.setFileName(file.getName());

mbp.setDisposition(Part.ATTACHMENT);



Q: How do I create a multipart message with a part of any MIME type I choose?
A: The JavaMail API includes builtin support for the most common MIME types, but to create a message that includes data in a MIME type that JavaMail does not already understand, you'll need to supply that data to JavaMail in a byte stream format. The ByteArrayDataSource class in the javax.mail.util pacakge in JavaMail 1.4 and later, or included in source code in the demo directory of older versions of the JavaMail download package, can help. This class will take a String, byte array, or InputStream and create a DataSource object that you can use as follows:

MimeBodyPart mbp = new MimeBodyPart();

String data = "any ASCII data";

DataSource ds = new ByteArrayDataSource(data, "application/x-any");

mbp.setDataHandler(new DataHandler(ds));



You can specify any MIME type that you want. The MimeBodyPart object can then be added to a MimeMultipart object in the usual way.

Note that if you create a ByteArrayDataSource with an InputStream, it first copies all of the data in the stream into memory. This is necessary because a DataSource needs to be able to supply multiple InputStream objects so that JavaMail can read the data once to determine what Content-Transfer-Encoding is appropriate, and then read the data again to include the data in the message.

Q: What is "disconnected support"?
A: A mail client supporting disconnected operation will allow the user to access messages in a remote message store (e.g., IMAP), cache (parts of) some of those messages locally, and break the connection to the server. While in this disconnected state, the mail client can access the messages that have been cached, possibly deleting them or saving them to other folders. When the mail client next connects to the remote message store, the changes made locally will be synchronized with the remote store. Similarly, disconnected support may allow the client to "send" messages when there is no connection to the server, with the messages being queued until a connection to the server is available. See also RFC1733.

Q: How do I support disconnected operation using the JavaMail APIs?
A: The JavaMail API specification defines interfaces that can be used by a mail client to support disconnected operation. Our IMAP provider implements these interfaces (the UIDFolder interfaces).

Q: How do I send secure email using the JavaMail APIs?
A: The JavaMail APIs currently have no support for sending or receiving secure email. The architecture of the JavaMail APIs allows such support to be easily added later, by us or by third parties. Information on the current Email security standards (S/MIME and PGP) can be found at http://www.imc.org/smime-pgpmime.html. Please browse our Third Party Products page for solutions from other vendors.

Q: The writeTo() method generates message text with lines that are neither the canonical MIME representation of the data (i.e., using CRLF to terminate lines), nor using the canonical line separator of my platform (e.g., "\n" on UNIX). How do I get either of these representations if I need them?
A: In either case you'll need to create an appropriate FilterOutputStream to hand to writeTo(). The FilterOutputStream will need to accept lines with any of the common line terminators and write out lines with only the desired line terminator. The following are examples of such filters. NewlineOutputStream converts to the local platform's line terminator and is useful when writing a message to a file. CRLFOutputStream converts to the MIME canonical CRLF line terminator and is useful when the canonical MIME format is needed (e.g., to compute a digital signature).

Q: Can I use the JavaMail APIs to implement a mail server?
A: The JavaMail APIs were not intended to help you implement a mail server. Nonetheless, some of the utility classes, such as the MIME message parsing classes, might be of use to you. In general you'll find that the JavaMail API errs on the side of "simple" instead of "robust". That's appropriate for a mail client, but a mail server would likely make different tradeoffs.

Q: Can I use the JavaMail APIs to add new user accounts to my mail server, remove user accounts from my mail server, or change the passwords for user accounts on my mail server?
A: The JavaMail API does not include any facilities for adding, removing, or changing user accounts. There are no standards in this area; every mail server handles this differently.

Q: Can I use the JavaMail APIs to access my address book on my mail server? [new!]
A: The JavaMail API does not include any facilities for accessing an address book. There are no standards in this area; every mail server handles this differently. If you can figure out how your server does it, you might be able to find a Java API to access it. For example, if your server stores address books in LDAP, you could use the JNDI API to access it.

Q: Why doesn't the MimeMessage class implement Serializable so that I can serialize a message to disk and read it back later?
A: The JavaMail API was designed to layer on top of existing email systems, using existing message formats. The ability to use Java serialization was neither essential nor useful for such implementations, and thus was not considered a goal of the JavaMail API.

The hard part about serializing a Message is retaining the pointers to the Folder, Store, and Session. If you only want to save the content of the message, and not the object itself, the writeTo method of a message gives you everything you need. If you want to create an entire email system based on serialized messages, you should be able to subclass Message et. al. and implement Serializable in your subclass.

If you want to serialize other objects of your own that reference MimeMessages, the writeObject method of your object can use the writeTo method of MimeMessage, and the readObject method of your object can use the MimeMessage constructor that takes an InputStream. Your class will need to provide a Session when constructing the MimeMessage.

Q: How do I write a Service Provider?
A: Please read the Service Provider documentation for details. In general, if you want to write a Store provider, you subclass javax.mail.Store, javax.mail.Folder, possibly javax.mail.Message and a few others. For a Transport provider, you subclass javax.mail.Transport, possibly javax.mail.Message and a few others. Then you add the entry describing your provider to the javamail.providers registry. If you're interested in writing a service provider for a protocol or messaging system not currently supported by the JavaMail API implementation, please contact us at javamail@Sun.COM.

Q: I'm having trouble logging into my Microsoft Exchange server, even though I'm sure I'm using the correct username and password, what could I be doing wrong?
A: When logging in to Exchange you need to use a username that's more than your simple login name. For example, if your email address is "J.User@server.com", your Windows NT login name is "juser", your NT domain name is "dom", and your Exchange mailbox name is "Joe User", then you would need to use a username of "dom\juser\J.User" when logging in using JavaMail.

Q: How do I encode a binary file before sending it and how do I decode it when I receive it?
A: You don't need to! JavaMail will automatically determine an appropriate encoding to use for your message parts before sending the message, and will automatically decode message parts when reading them. The getInputStream method will return the decoded data.

Q: If I don't need to encode and decode attachments myself, when should I use the MimeUtility methods?
A: The MimeUtility methods are useful in cases that JavaMail doesn't handle automatically for you. One such case that occurs frequently is encoding of filenames. The base MIME spec does not allow header parameter values (such as the filename parameter) to be encoded in the same way that (e.g.) the Subject header may be encoded. This restricts parameter values, and thus filenames, to ASCII. However, some mailers actually do encode non-ASCII filenames using the MIME text encoding. Applications that wish to interoperate with such non-standard mailers can use the encodeText method to encode filenames before calling the MimeBodyPartsetFileName method, and can use the decodeText method to decode returned filenames. See also this entry below if you need to encode filenames.

Q: I have data that's already encoded in (e.g.) base64, how do I tell JavaMail to send this data without re-encoding it?
A: Use the PreencodedMimeBodyPart class, new in JavaMail 1.4.

Q: Even though JavaMail does all the encoding and decoding for me, I need to manually control the encoding for some body parts.
A: In the rare case that you need to control the encoding, there are several ways to override JavaMail's default behavior. A simple approach is as follows. After creating the entire message, call msg.saveChanges() and then use something like mbp.setHeader("Content-Transfer-Encoding", "base64") to force base64 encoding for the given body part.

Another approach is to subclass MimeBodyPart and override the updateHeaders method so that it first calls super.updateHeaders() and then sets the Content-Transfer-Encoding header as above.

Q: Why doesn't JavaMail properly encode and decode filenames in non-ASCII character sets?
A: The filename is stored as a parameter in MIME headers. Encoded filenames of the form =?ISO-8859-15?B?5OTkLUluZm8ucGRm?= are not part of the MIME spec. A filename of the form =?A?B?C?= is a perfectly valid filename, not an incorrectly encoded filename. JavaMail does not encoded and decode filenames by default because doing so would violate the MIME spec.

The base MIME spec does not allow for encoding parameters. RFC 2231 defines a new way to include encoded paramters, including filenames, in MIME headers. It is not compatible with the de facto way that many applications illegally encode filenames. Even though JavaMail supports RFC 2231, that alone does not allow JavaMail to interoperate with these existing programs. As far as I know, very few existing programs support RFC 2231.

If you choose to violate the MIME spec, in order to interoperate with other programs that also violate the MIME spec, JavaMail gives you all the tools you need to do so. Starting with JavaMail 1.4, setting the System properties "mail.mime.encodefilename" and "mail.mime.decodefilename" to "true" will cause JavaMail to encode and decode the filename parameter.

Applications using earlier versions of JavaMail can use the following workaround to encode a filename:

mbp.setFileName(MimeUtility.encodeText(filename));

The workaround for decoding a filename is equally simple:

String filename = MimeUtility.decodeText(part.getFileName());

Debugging

Q: How do I debug my application that uses JavaMail APIs?
A: Turn on session debugging by invoking the method setDebug(true) on the Session object in your code. That will cause debug information to be printed to the console, including a protocol trace. If you passed the System properties to the Session when you created it, you can simply run your program with java -Dmail.debug=true ...
If you think that you found a bug in JavaMail, send us this trace along with a test case that reproduces the problem, the platform you are using, the version of the JDK you are using, and the name and version of the mail servers (IMAP, SMTP) that you are using.

Q: How do I debug problems connecting to my mail server?
A: The first thing to do when debugging such problems is to determine whether it's a Java problem or a networking problem. Use telnet to try to connect to the remote system. For example, if you're having trouble connecting to the POP3 server named mail.example.com, you would use:

telnet mail.example.com 110

If you're trying to connect to an SMTP server, use 25 instead of 110 for the port number. If you're trying to connect to an IMAP server use 143 for the port number.

If you get a greeting banner you can simply disconnect. If this works, your networking, name service, firewall, etc. are all set up correctly and your problem is most likely in your Java program.

If it doesn't work, you'll need to check your networking configuration or talk to your network administrator for help. Sometimes a firewall installed on your local machine or on your network will prevent you from connecting to the server. If telnet complains that it doesn't know the host name that you're using, most likely your name service (e.g., DNS) isn't properly configured to resolve internet host names. None of these problems are JavaMail or Java problems.

Usually, when you get a low level SocketException when connecting, the problem is due to your networking configuration. Usually it's not a Java problem.

If you've succeeded in connecting with telnet, the next thing to do is to turn on Session debugging and get the protocol trace when JavaMail tries to connect to the remote machine, as described above. This will often include more detailed error messages from the server that will indicate the real source of the problem.

Q: How do I debug problems connecting to my mail server using SSL?
A: Debugging SSL problems, and in particular certificate problems, can be difficult. The file SSLNOTES.txt included in the JavaMail download package includes some useful information. JavaMail uses the JDK's JSSE API to provide SSL support. You can find information about debugging JSSE problems in the JSSE Reference Guide.

Q: How do I debug problems with Java security permissions? [new!]
A: You can set the java.security.debug System property to debug problems with Java security permissions. To get the possible values for setting that property, the following command will print a help message: java -Djava.security.debug=help MyClass

Reading mail, IMAP

Q: I tried running your demos against my IMAP server, but I get an error.
A: First verify that you indeed have an email account on the IMAP server. Check with your system administrator about it. Turn debug mode on, by invoking the method setDebug(true) on the session object in your code. This will cause the IMAP protocol trace to be dumped on your screen. Send us this trace. The trace will be very useful to us for identifying the problem. If you can, please send us vendor information about your IMAP server.

Q: I can read messages from my IMAP server with other mail clients, but even though I can connect to the server using JavaMail, when I use JavaMail to read some messages it fails. Doesn't that mean there's a bug in JavaMail? [new!]
A: No, not usually. Most other mail clients make very little use of the rich IMAP protocol. They use the IMAP protocol as little more than a variant of the POP3 protocol, typically downloading the entire message to the client and parsing it in the client. This allows them to avoid all sorts of parsing and protocol bugs in many IMAP servers, but of course it comes at the cost of being less efficient because they don't take advantage of the IMAP protocol's ability to fetch only the parts of the message that are needed. These server bugs often manifest themselves as the following exception on the client: javax.mail.MessagingException: Unable to load BODYSTRUCTURE

The best approach when running into server bugs of this sort is to contact the vendor of the server and get them to fix their product. Contact javamail@sun.com and we'll help you pinpoint the problem so that you can report it to the server vendor. If you can't get a fix from the server vendor, the following technique will often allow you to work around these server bugs:

// Get the message object from the folder in the

// usual way, for example:

MimeMessage msg = (MimeMessage)folder.getMessage(n);

// Use the MimeMessage copy constructor to make a copy

// of the entire message, which will fetch the entire

// message from the server and parse it on the client:

MimeMessage cmsg = new MimeMessage(msg);

// The cmsg object is disconnected from the server so

// setFlags will have no effect (for example). Use

// the original msg object for such operations. Use

// the cmsg object to access the content of the message.



Q: The IMAP provider seems to lose data when I fetch messages with large attachments.
A: This is due to bugs in the partial fetch implementation of your IMAP server. To workaround this server bug, set the "mail.imap.partialfetch" property to "false". Refer to NOTES.txt from the JavaMail package for more information.

Q: Does the IMAP provider cache the retrieved data?
A: The IMAP provider fetches the data for a message from the server only when necessary. (The javax.mail.FetchProfile can be used to optimize this). The header and bodystructure information, once fetched, is always cached within the Message object. However, the content of a bodypart is not cached. So each time the content is requested by the client (either using getContent() or using getInputStream()), a new FETCH request is issued to the server. The reason for this is that the content of a message could be potentially large, and if we cache this content for a large number of messages, there is the possibility that the system may run out of memory soon since the garbage collector cannot free the referenced objects. Clients should be aware of this and must hold on to the retrieved content themselves if needed.

Q: I want to move messages between folders. Should I use appendMessages() or copyMessages()?
A: Use copyMessages() if the messages to be copied/moved belong to the folder on which this method is being invoked. This is because some implementations can optimize this operation if the source and destination folder belong to the same backend Store. Otherwise, use appendMessages().

Q: Retrieving large message bodies seems inefficient at times.
A: If you are using the Sun IMAP provider, you could try increasing the mail.imap.fetchsize property (the current default is 16k). This will cause data to be fetched from the server in larger chunks. Note that you risk the possibility of the JVM running out of memory when you do this.

Q: I get OutOfMemory errors when loading this large binary attachement.
A: Increase the maximum JVM heapsize at startup. Use the "-mx" option if using the standard JVM from Sun. Don't keep references to the "content" of messages not being used. In certain cases, you could try streaming the message content (using getInputStream()) as raw bytes, use and then discard the used data chunks.

Q: Why do I get the UnsupportedDataTypeException when I invoke getContent() on a bodypart?
A: The getContent() method returns a Java object that represents the bodypart content. For this to work, a JAF DataContentHandler corresponding to the content's MIME type must be registered. Otherwise, the UnsupportedDataTypeException will be thrown. In this case, you can use the getInputStream() method to retrieve the content as a stream of bytes. See the JAF docs for details on how to create and register your own DataContentHandlers.

Q: Why do I get the UnsupportedEncodingException when I invoke getContent() on a bodypart that contains text data?
A: Textual bodyparts (i.e., bodyparts whose type is "text/plain", "text/html", or "text/xml") return Unicode String objects when getContent() is used. Typically, such bodyparts internally hold their textual data in some non Unicode charset. JavaMail (through the corresponding DataContentHandler) attempts to convert that data into a Unicode string. The underlying JDK's charset converters are used to do this. If the JDK does not support a particular charset, then the UnsupportedEncodingException is thrown. In this case, you can use the getInputStream() method to retrieve the content as a stream of bytes. For example:

String s;

if (part.isMimeType("text/plain")) {

try {

s = part.getContent();

} catch (UnsupportedEncodingException uex) {

InputStream is = part.getInputStream();

/*

* Read the input stream into a byte array.

* Choose a charset in some heuristic manner, use

* that charset in the java.lang.String constructor

* to convert the byte array into a String.

*/

s = convert_to_string(is);

} catch (Exception ex) {

// Handle other exceptions appropriately

}

}



There are some commonly used charsets that the JDK does not yet support. You can find support for some of these additional charsets in the JCharset package at http://www.freeutils.net/source/jcharset/.

You can also add an alias for an existing charset already supported by the JDK so that it will be known by an additional name. You can create a charset provider for the "bad" charset name that simply redirects to an existing charset provider; see the following code. Create an appropriate CharsetProvider subclass and include it along with the META-INF/services file and the JDK will find it. Obviously you could get significantly more clever and redirect all unknown charsets to "us-ascii", for instance.

==> TestCharsetProvider.java <==

import java.nio.charset.*;

import java.nio.charset.spi.*;

import java.util.*;

public class TestCharsetProvider extends CharsetProvider {

private static final String badCharset = "cp-1252";

private static final String goodCharset = "cp1252";

public Charset charsetForName(String charset) {

if (charset.equals(badCharset))

return Charset.forName(goodCharset);

return null;

}

public Iterator charsets() {

return null;

}

}

==> META-INF/services/java.nio.charset.spi.CharsetProvider <==

TestCharsetProvider



Sending mail, SMTP

Q: How do I reply to a message?
A: To reply to a message, use the reply method on the Message object. This method will return a new object with the headers set appropriately for a reply. You'll need to supply the content of the message yourself. If you have the content of the original message as a String, you can use a simple method such as the following to create the prototypical reply text, which inserts "> " in front of each line:

String text = (String)msg.getContent();

Message reply = msg.reply();

String replyText = text.replaceAll("(?m)^", "> ");

// allow user to edit replyText,

// e.g., using a Swing GUI or a web form

reply.setText(replyText);



Q: How do I forward a message?
A: The approach used to forward a message depends on how you want to present the forwarded message. It's straightforward to create a new MimeMessage, address it appropriately, and attach an existing message as an attachment to the new message. To attach the original message to the new message, use code such as:

MimeBodyPart mbp = new MimeBodyPart();

mbp.setContent(forwardedMsg, "message/rfc822");

mp.addPart(mbp);



If instead you want to create the new message with the text of the original message included in the new message, to forward the message "inline", you can use an approach such as the following:

String text = (String)forwardedMsg.getContent();

String forwardedText = String.format(

"\n\n-------- Original Message --------\n" +

"Subject: %s\nDate: %s\nFrom: %s\nTo: %s\n",

forwardedMsg.getSubject(),

forwardedMsg.getSentDate(),

forwardedMsg.getFrom()[0],

formatAddressList(

forwardedMsg.getRecipients(Message.RecipientType.TO)));

// allow user to edit forwardedText,

// e.g., using a Swing GUI or a web form

msg.setText(forwardedText);



(You'll have to write the formatAddressList method using the toUnicodeString method of InternetAddress. You'll also want to include appropriate error checking and test for null values.)

Q: How do I send HTML mail?
A: There are a number of demo programs included with the distribution that show how to send HTML mail. If you want to send a simple message that has HTML instead of plain text, see the sendhtml.java program in the demo directory. If you want to send an HTML file as an attachment, see the sendfile.java example that shows how to send any file as an attachment.

Q: How do I send mail with formatted text using different fonts and colors?
A: The simplest approach is to send a message using HTML text. See above.

Q: How do I send mail with both plain text as well as HTML text so that each mail reader can choose the format appropriate for it?
A: You'll want to send a MIME multipart/alternative message. You construct such a message essentially the same way you construct a multipart/mixed message, using a MimeMultipart object constructed using new MimeMultipart("alternative"). You then insert the text/plain body part as the first part in the multpart and insert the text/html body part as the second part in the multipart. You'll need to construct the plain and html parts yourself to have appropriate content. See RFC2046 for details of the structure of such a message.

Q: How do I send HTML mail that includes images?
A: The simplest approach is to send HTML text with image tags that reference images on a public web site. In this approach the images aren't actually included in the message, and so won't be visible if the user is not connected to the Internet when they read the message. Note also that some mailers will refuse to display images that are on remote sites.

Alternatively, you can construct a MIME multipart/related message. See RFC2387 for details of the structure of such a message.

Q: What's the difference between the Transport methods send and sendMessage?
A: The send() method is a static method and can be used without needing an instance of a Transport object. It is intended for the common, simple case of sending a single message using the default transport. Internally, the send() method will first call the saveChanges() method on the message. It will then create an appropriate new Transport object, call the Transport's connect() method, call the Transport's sendMessage() method to actually send the message, call the Transport's close() method, and finally abandon the new instance of the Transport object to be collected by the garbage collector. (Actually, it's rather more complicated than that, but that's the general idea.)

As you can see, the static send() convenience method is built on the more general per-instance sendMessage() method. There are a number of reasons for an application to use the sendMessage() method directly. The most common reasons are to improve performance by sending more than one message during a single connection, or to manually manage the connection so as to provide authentication information.

Q: When I try to send a message I get an error like SMTPSendFailedException: 530, Address requires authentication. [updated!]
A: You need to authenticate to your SMTP server. The package javadocs for the com.sun.mail.smtp package describe several methods to do this. The easiest is often to replace the call Transport.send(msg); with

String protocol = "smtp";

props.put("mail." + protocol + ".auth", "true");

...

Transport t = session.getTransport(protocol);

try {

t.connect(username, password);

t.sendMessage(msg, msg.getAllRecipients());

} finally {

t.close();

}



You'll have to supply the appropriate username and password needed by your mail server. Note that you can change the protocol to "smtps" to make a secure connection over SSL.

Q: I need to authenticate to my SMTP server so I call trans.connect(host, user, password) and then trans.send(msg) to send the message, but it's not working.
A: You should call trans.sendMessage(msg, addrs) to send the message. As described above, the send method is a static convenience method that acquires its own Transport object and creates its own connection to use for sending; it does not use the connection associated with any Transport object through which it is invoked.

Q: I modified this message, but the headers do not reflect the changes.
A: You should call saveChanges() after you create a new message or modify an existing message. This will cause the headers to be reset and reflect your changes. Note that the Transport.send(Message) method calls this implicitly. So if all you are doing is sending the modified message, you can skip calling saveChanges() yourself. saveChanges() is a potentially expensive operation (especially for large or deeply nested messages), so call it only when needed.

Q: I set a particular value for the Message-ID header of my new message, but when I send this message that header is rewritten.
A: A new value for the Message-ID field is set when the saveChanges method is called (usually implicitly when a message is sent), overwriting any value you set yourself. If you need to set your own Message-ID and have it retained, you will have to create your own MimeMessage subclass, override the updateMessageID method and use an instance of this subclass.

class MyMessage extends MimeMessage {

...

protected void updateMessageID() throws MessagingException {

setHeader("Message-ID", "my-message-id");

}

...

}



Q: Why do I get an UnsupportedDataTypeException when sending this new message that I created?
A: You probably set some content for your message using the setContent(Object o, String type) method. For this to work, there must be a JAF DataContentHandler registered for the given "type". If not, you will get the UnsupportedDataTypeException. See the JAF documents ( http://java.sun.com/products/javabeans/jaf/) for more information. In most cases the simplest workaround is to use a ByteArrayDataSource as described above.

Q: How can I explicitly set the SMTP FROM: attribute when sending a message?
A: The mail.smtp.from property can be used to set the SMTP FROM: attribute. If this property if absent, the message's From attribute is used. If multiple threads need to send mail simultaneously, and each needs to set the From attribute, each thread should use its own Session object with its own Properties object. The mail.smtp.from property can then be set on each Properties object for each Session (and thus each thread) independently. Alternatively, each thread can use the com.sun.mail.SMTPMessage class. The setEnvelopeFrom method on that class can be used to set this value. With this approach, all threads can use the same Session.

Q: I want to repeatedly send messages, to a different set of recipients each time. But invoking Transport.send(Message) causes a new Transport session to be established each time. This is suboptimal in this case, so how do I get around this?
A: Create an instance of the appropriate Transport object, connect to it and invoke the sendMessage() method repeatedly. For example:

MimeMessage msg = ...;

// construct message

msg.saveChanges();

Transport t = session.getTransport("smtp");

t.connect();

for (int i = 0; .....) {

t.sendMessage(msg, new Address[] { recipients[i] });

}

t.close();



Q: I get "MessagingException: 501 HELO requires domain address" when trying to send a message.
A: The SMTP provider uses the results of InetAddress.getLocalHost().getHostName() in the SMTP HELO command. If that call fails to return any data, no name is sent in the HELO command. Check your JDK and name server configuration to ensure that that call returns the correct data. You may also set the "mail.smtp.localhost" property to the name you want to use for the HELO command.

Q: If I send a message to a bad address, why don't I get a SendFailedException or TransportEvent indicating that the address is bad?
A: There is no end-to-end address verification on the Internet. Often a message will need to be forwarded to several mail servers before reaching one that can determine whether or not it can deliver the message. If a failure occurs in one of these later steps, the message will typically be returned to the sender as undeliverable. A successful "send" indicates only that the mail server has accepted the message and will try to deliver it.

Q: When a message can't be delivered, a failure message is returned. How can I detect these "bounced" messages?
A: While there is an Internet standard for reporting such errors (the multipart/report MIME type, see RFC1892), it is not widely implemented yet. RFC1211 discusses this problem in depth, including numerous examples.

In Internet email, the existence of a particular mailbox or user name can only be determined by the ultimate server that would deliver the message. The message may pass through several relay servers (that are not able to detect the error) before reaching the end server. Typically, when the end server detects such an error, it will return a message indicating the reason for the failure to the sender of the original message. There are many Internet standards covering such Delivery Status Notifications but a large number of servers don't support these new standards, instead using ad hoc techniques for returning such failure messages. This makes it very difficult to correlate a "bounced" message with the original message that caused the problem. (Note that this problem is completely independent of JavaMail.) JavaMail now includes support for parsing Delivery Status Notifications; see the NOTES.txt file in the JavaMail package for details.

There are a number of techniques and heuristics for dealing with this problem - none of them perfect. One technique is Variable Envelope Return Paths, described at http://cr.yp.to/proto/verp.txt.

Q: When I construct an InternetAddress object, why don't I get an exception if the address is illegal?
A: The InternetAddress class only checks the syntax of the address. As discussed above, the InternetAddress class is not able to determine whether the address actually exists as a legal address. It is not even possible to verify the host name if the application is running behind a firewall or isn't currently connected to the Internet.

Q: When I try to send a message, why do I get javax.mail.SendFailedException: 550 Unable to relay for my-address?
A: This is not a JavaMail problem. This is an error reply from your SMTP mail server. It indicates that your mail server is not configured to allow you to send mail through it. Typically, mail servers for an organization will be configured to allow mail from within the organization to be sent to other addresses within the organization, or to addresses external to the organization. It will also typically allow mail coming from an address external to an organization to be sent to addresses within the orgnaization. What it will typically not allow is mail coming from an address external to the organization to be sent (relayed) to another address also external to the organization. The configuration of the mail server determines whether such relaying is allowed, and which addresses are considered internal vs. external. Often mail servers will require you to authenticate before they will relay messages.

Q: When I try to send a message to (for example) Yahoo, why do I get an error that says "connection refused"?
A: The host you're trying to connect to is most likely not running a mail server. If you're trying to connect to a web mail service such as Yahoo, you can't usually use the web host name (e.g., "yahoo.com") since this host doesn't run the required mail server. Instead, you'll need to learn the name of the host running the required mail server; contact your web mail provider for this information. You can find this information for Yahoo at http://help.yahoo.com/help/us/mail/pop/pop-02.html. Note that some web mail providers don't offer this service, instead allowing you to access your mail only through a browser.

If you're not trying to connect to a web mail account, but instead are trying to connect to a host on your local network, then most likely the host you're trying to connect to is not running a mail server. Sometimes this will occur if you forget to set (for example) the "mail.smtp.host" property, which will cause you to try to connect to "localhost". Most Windows machines do not run a mail server, although many UNIX (Solaris, Linux, etc.) machines do. Thus, attempts to connect to "localhost" on Windows machines will usually fail with a "connection refused" error.

Q: When sending mail, why does it fail with an exception that includes a message something like 553 To send mail, first check your mail with a valid POP account?
A: In order to prevent their use to send spam, some mail servers will require you to have a valid POP3 account and require you to login to that account before they'll let you send mail through that mail server. This is simple to handle in JavaMail. When you know that you're dealing with such a mail server, make sure you connect to your POP3 Store on that mail server before sending mail.

POP3

Q: I want to delete messages on a POP3 server. I set the DELETED flag on those messages. Then I call the expunge() method, but I get a MethodNotSupportedException. How do I delete messages when I use Sun's POP3 provider?
A: The expunge() method is not supported by the POP3 provider. Instead, close the folder with the expunge flag set to true. That is, invoke folder.close(true).

Q: How can I retrieve POP3 UIDLs in messages obtained from Sun's POP3 provider?
A: This is possible with the POP3 provider. See the com.sun.mail.pop3 package documentation for details.

Q: How can I tell which messages are new with POP3?
A: The POP3 protocol doesn't provide support for any permanent flags so the RECENT flag is of no use. The com.sun.mail.pop3 package documentation discusses several strategies for dealing with this problem.

Q: Why does hasNewMessages() always return false when using POP3?
A: The POP3 protocol provides no way to determine whether a folder has new messages.

Q: I set up a MessageCountListener (as demonstrated in the monitor program) but I'm never notified of new mail in my POP3 INBOX.
A: The POP3 protocol does not allow the client to see new messages delivered to the INBOX while the INBOX is open. The application must close the INBOX and reopen it in order to see any new messages. You will never be notified of new mail using the MessageCountListener interface with POP3. See the com.sun.mail.pop3 package documentation for more information.

Q: Why does getReceivedDate() return null when using POP3?
A: The POP3 protocol does not provide information about when a message was received. It may be possible to guess at the received date by looking at some message headers such as the Received header, but this is not very reliable.

Q: When using POP3 I get complaints about the SocketFetcher class.
A: Most likely you have more than one version of pop3.jar or mail.jar in your CLASSPATH. Check the setting of CLASSPATH and check the "jre/lib/ext" directory in the JDK.

Q: When using POP3 I get complaints about the contentStream field.
A: The error usually looks like:

java.lang.NoSuchFieldError: contentStream at

com.sun.mail.pop3.POP3Message.getContentStream(POP3Message.java:115)

As above, you've mixed versions of the POP3 provider and mail.jar. You probably have an older version of mail.jar in your CLASSPATH before the newer version that includes the POP3 provider.

Q: How do I access or create folders other than INBOX on my POP3 server?
A: You can't. POP3 servers only support a single mailbox per user. Most mail readers that use POP3 also maintain a local message store into which they copy incoming messages (from the POP3 INBOX) and allow you to file messages in other folders. See this item for more information about local store providers.

Q: Why does the getSize method return a negative number when using POP3?
A: Your POP3 server is broken. The POP3 provider uses the TOP command to fetch the headers for the message and the LIST command to determine the size of the entire message. It then subtracts the two values to determine the size of the message body. If the server reports the size of the entire message incorrectly, you may get a negative number. You can set the property "mail.pop3.disabletop" to "true" to disable the use of the TOP command, but note that this will cause any access to the message headers to fetch the entire message.

Q: I'm having problems using POP3 with Microsoft Exchange.
A: Some versions of Microsoft Exchange do not implement the POP3 protocol properly. They return different headers from the TOP command than they do from the RETR command. This can cause all sorts of strange failures in JavaMail. One solution is to disable use of the TOP command, as described above. Another approach that works in some cases os to tell JavaMail to forget about the headers it retrieved using the TOP command after retrieving the entire message using the RETR command. To do this, set the property "mail.pop3.forgettopheaders" to "true".

JavaMail in servlets

Q: Can I use JavaMail in servlets?
A: Yes, see the Installation and Configuration section above for more details. The JavaMail API is also a required part of the Java Platform, Enterprise Edition (Java EE). No installation or configuration is necessary when using JavaMail in a Java EE product, it's just there!

Q: My web application uses JavaMail to attach and send a file that the user specifies, but my application can't find the file.
A: If the user species the filename in an HTML form in the browser, the filename is normally the name of a file on the user's machine, not on the server. The file will need to be uploaded to the server before JavaMail can access it. The Apache Jakarta Commons FileUpload package can help.

JavaMail in applets

Q: Can I use JavaMail in applets?
A: Yes, JavaMail will work in applets in browsers that support the required JDK version. The Java Plug-in may be required to provide such support.

Q: What are the security implications of using JavaMail in an applet?
A: One of the biggest issues with using JavaMail in applets is the default applet security restrictions. These restrictions only allow applets to connect to the host from which they were loaded. Thus, for such applets to use JavaMail, the mail server will need to be located on the same machine as the web server from which the applet is loaded. You can find more information on the applet security model at http://java.sun.com/sfaq/.

Q: Ok, maybe I really don't want to use an applet, what should I do instead?
A: In general, we recommend use of a servlet (or JSP) to collect a mail message and send it using JavaMail. The demo servlet included in the JavaMail download package illustrates this approach. The Email Web Application demo program on the Sun Developer Network illustrates another approach using JavaServer Pages.