v.io/x/ref/lib/vdl/codegen/java: fix Javadocs for VDL files and cleanup interfaces

Change-Id: I9c1fe49d80400b116972cfd48ea2a8a4dba59208
diff --git a/lib/vdl/codegen/java/file_array.go b/lib/vdl/codegen/java/file_array.go
index af38b90..9e069c3 100644
--- a/lib/vdl/codegen/java/file_array.go
+++ b/lib/vdl/codegen/java/file_array.go
@@ -18,26 +18,40 @@
 
 package {{.Package}};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 @io.v.v23.vdl.ArrayLength({{.Length}})
 {{ .AccessModifier }} class {{.Name}} extends io.v.v23.vdl.VdlArray<{{.ElemType}}> {
     private static final long serialVersionUID = 1L;
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given underlying array.
+     *
+     * @param arr underlying array
+     */
     public {{.Name}}({{.ElemType}}[] arr) {
         super(VDL_TYPE, arr);
     }
 
+    /**
+     * Creates a new zero-value instance of {@link {{.Name}}}.
+     */
     public {{.Name}}() {
         this({{.ZeroValue}});
     }
 
     {{ if .ElemIsPrimitive }}
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given underlying array.
+     *
+     * @param arr underlying array
+     */
     public {{.Name}}({{ .ElemPrimitiveType }}[] arr) {
         super(VDL_TYPE, convert(arr));
     }
@@ -60,12 +74,12 @@
 	elems := strings.TrimSuffix(strings.Repeat(javaZeroValue(tdef.Type.Elem(), env)+", ", tdef.Type.Len()), ", ")
 	zeroValue := fmt.Sprintf("new %s[] {%s}", elemType, elems)
 	data := struct {
-		FileDoc           string
 		AccessModifier    string
 		Doc               string
 		ElemType          string
 		ElemIsPrimitive   bool
 		ElemPrimitiveType string
+		FileDoc           string
 		Length            int
 		Name              string
 		Package           string
@@ -74,12 +88,12 @@
 		VdlTypeString     string
 		ZeroValue         string
 	}{
-		FileDoc:           tdef.File.Package.FileDoc,
 		AccessModifier:    access,
-		Doc:               javaDocInComment(tdef.Doc),
+		Doc:               javaDoc(tdef.Doc, tdef.DocSuffix),
 		ElemType:          elemType,
 		ElemIsPrimitive:   !isClass(tdef.Type.Elem(), env),
 		ElemPrimitiveType: javaType(tdef.Type.Elem(), false, env),
+		FileDoc:           tdef.File.Package.FileDoc,
 		Length:            tdef.Type.Len(),
 		Name:              name,
 		Package:           javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
diff --git a/lib/vdl/codegen/java/file_client_factory.go b/lib/vdl/codegen/java/file_client_factory.go
index 626c5e0..b16bf38 100644
--- a/lib/vdl/codegen/java/file_client_factory.go
+++ b/lib/vdl/codegen/java/file_client_factory.go
@@ -7,7 +7,6 @@
 import (
 	"bytes"
 	"log"
-	"path"
 
 	"v.io/x/ref/lib/vdl/compile"
 	"v.io/x/ref/lib/vdl/vdlutil"
@@ -17,39 +16,54 @@
 // Source(s):  {{ .Sources }}
 package {{ .PackagePath }};
 
-/* Factory for binding to {{ .ServiceName }}Client interfaces. */
-{{.AccessModifier}} final class {{ .ServiceName }}ClientFactory {
-    public static {{ .ServiceName }}Client bind(final java.lang.String name) {
-        return bind(name, null);
+/**
+ * Factory for {@link {{ .ServiceName }}Client}s.
+ */
+public final class {{ .ServiceName }}ClientFactory {
+    /**
+     * Creates a new {@link {{ .ServiceName }}Client}, binding it to the provided name.
+     *
+     * @param name name to bind to
+     */
+    public static {{ .ServiceName }}Client get{{ .ServiceName }}Client(final java.lang.String name) {
+        return get{{ .ServiceName }}Client(name, null);
     }
-    public static {{ .ServiceName }}Client bind(final java.lang.String name, final io.v.v23.Options vOpts) {
+
+    /**
+     * Creates a new {@link {{ .ServiceName }}Client}, binding it to the provided name and using the
+     * provided options.  Currently supported options are:
+     * <p><ul>
+     * <li>{@link io.v.v23.OptionDefs#CLIENT}, which specifies a {@link io.v.v23.rpc.Client} to use for all rpc calls.</li>
+     * </ul>
+     * 
+     * @param name name to bind to
+     * @param opts creation options
+     */
+    public static {{ .ServiceName }}Client get{{ .ServiceName }}Client(final java.lang.String name, final io.v.v23.Options opts) {
         io.v.v23.rpc.Client client = null;
-        if (vOpts != null && vOpts.get(io.v.v23.OptionDefs.CLIENT) != null) {
-            client = vOpts.get(io.v.v23.OptionDefs.CLIENT, io.v.v23.rpc.Client.class);
+        if (opts != null && opts.get(io.v.v23.OptionDefs.CLIENT) != null) {
+            client = opts.get(io.v.v23.OptionDefs.CLIENT, io.v.v23.rpc.Client.class);
         }
-        return new {{ .StubName }}(client, name);
+        return new {{ .ServiceName }}ClientImpl(client, name);
     }
+
+    private {{ .ServiceName }}ClientFactory() {}
 }
 `
 
-// genJavaClientFactoryFile generates the Java file containing client bindings for
-// all interfaces in the provided package.
+// genJavaClientFactoryFile generates the Java client factory file.
 func genJavaClientFactoryFile(iface *compile.Interface, env *compile.Env) JavaFileInfo {
 	javaServiceName := vdlutil.FirstRuneToUpper(iface.Name)
 	data := struct {
-		FileDoc        string
-		AccessModifier string
-		Sources        string
-		ServiceName    string
-		PackagePath    string
-		StubName       string
+		FileDoc     string
+		Sources     string
+		ServiceName string
+		PackagePath string
 	}{
-		FileDoc:        iface.File.Package.FileDoc,
-		AccessModifier: accessModifierForName(iface.Name),
-		Sources:        iface.File.BaseName,
-		ServiceName:    javaServiceName,
-		PackagePath:    javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
-		StubName:       javaPath(javaGenPkgPath(path.Join(iface.File.Package.GenPath, iface.Name+"ClientStub"))),
+		FileDoc:     iface.File.Package.FileDoc,
+		Sources:     iface.File.BaseName,
+		ServiceName: javaServiceName,
+		PackagePath: javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
 	}
 	var buf bytes.Buffer
 	err := parseTmpl("client factory", clientFactoryTmpl).Execute(&buf, data)
diff --git a/lib/vdl/codegen/java/file_client_stub.go b/lib/vdl/codegen/java/file_client_impl.go
similarity index 63%
rename from lib/vdl/codegen/java/file_client_stub.go
rename to lib/vdl/codegen/java/file_client_impl.go
index fd28e07..7b845f9 100644
--- a/lib/vdl/codegen/java/file_client_stub.go
+++ b/lib/vdl/codegen/java/file_client_impl.go
@@ -14,28 +14,40 @@
 	"v.io/x/ref/lib/vdl/vdlutil"
 )
 
-const clientStubTmpl = header + `
+const clientImplTmpl = header + `
 // Source(s):  {{ .Source }}
 package {{ .PackagePath }};
 
-/* Client stub for interface: {{ .ServiceName }}Client. */
-{{ .AccessModifier }} final class {{ .ServiceName }}ClientStub implements {{ .FullServiceName }}Client {
+/**
+ * Implementation of the {@link {{ .ServiceName }}Client} interface.
+ */
+final class {{ .ServiceName }}ClientImpl implements {{ .FullServiceName }}Client {
     private final io.v.v23.rpc.Client client;
     private final java.lang.String vName;
 
-    {{/* Define fields to hold each of the embedded object stubs*/}}
+    {{/* Define fields to hold each of the embedded object impls*/}}
     {{ range $embed := .Embeds }}
-    {{/* e.g. private final com.somepackage.gen_impl.ArithStub stubArith; */}}
-    private final {{ $embed.StubClassName }} {{ $embed.LocalStubVarName }};
+    {{/* e.g. private final com.somepackage.ArithClient implArith; */}}
+    private final {{ $embed.FullName }}Client impl{{ $embed.Name }};
     {{ end }}
 
-    public {{ .ServiceName }}ClientStub(final io.v.v23.rpc.Client client, final java.lang.String vName) {
+    /**
+     * Creates a new instance of {@link {{ .ServiceName }}ClientImpl}.
+     *
+     * @param client Vanadium client
+     * @param vName  remote server name
+     */
+    public {{ .ServiceName }}ClientImpl(final io.v.v23.rpc.Client client, final java.lang.String vName) {
         this.client = client;
         this.vName = vName;
-        {{/* Initialize the embeded stubs */}}
+        {{/* Initialize the embeded impls */}}
         {{ range $embed := .Embeds }}
-        this.{{ $embed.LocalStubVarName }} = new {{ $embed.StubClassName }}(client, vName);
-         {{ end }}
+        {
+            io.v.v23.Options opts = new io.v.v23.Options();
+            opts.set(io.v.v23.OptionDefs.CLIENT, client);
+            this.impl{{ $embed.Name }} = {{ $embed.FullName }}ClientFactory.get{{ $embed.Name }}Client(vName, opts);
+        }
+        {{ end }}
     }
 
     private io.v.v23.rpc.Client getClient(io.v.v23.context.VContext context) {
@@ -48,12 +60,12 @@
 {{ range $method := .Methods }}
     {{/* The optionless overload simply calls the overload with options */}}
     @Override
-    {{ $method.AccessModifier }} {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.DeclarationArgs }}) throws io.v.v23.verror.VException {
+    public {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.DeclarationArgs }}) throws io.v.v23.verror.VException {
         {{if $method.Returns }}return{{ end }} {{ $method.Name }}(context{{ $method.CallingArgsLeadingComma }}, null);
     }
-    {{/* The main client stub method body */}}
+    {{/* The main client impl method body */}}
     @Override
-    {{ $method.AccessModifier }} {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.DeclarationArgs }}, io.v.v23.Options vOpts) throws io.v.v23.verror.VException {
+    public {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext context{{ $method.DeclarationArgs }}, io.v.v23.Options vOpts) throws io.v.v23.verror.VException {
         {{/* Start the vanadium call */}}
         // Start the call.
         final java.lang.Object[] _args = new java.lang.Object[]{ {{ $method.CallingArgs }} };
@@ -124,27 +136,26 @@
 {{/* Iterate over methods from embeded services and generate code to delegate the work */}}
 {{ range $eMethod := .EmbedMethods }}
     @Override
-    {{ $eMethod.AccessModifier }} {{ $eMethod.RetType }} {{ $eMethod.Name }}(final io.v.v23.context.VContext context{{ $eMethod.DeclarationArgs }}) throws io.v.v23.verror.VException {
-        {{/* e.g. return this.stubArith.cosine(context, [args]) */}}
-        {{ if $eMethod.Returns }}return{{ end }} this.{{ $eMethod.LocalStubVarName }}.{{ $eMethod.Name }}(context{{ $eMethod.CallingArgsLeadingComma }});
+    public {{ $eMethod.RetType }} {{ $eMethod.Name }}(final io.v.v23.context.VContext context{{ $eMethod.DeclarationArgs }}) throws io.v.v23.verror.VException {
+        {{/* e.g. return this.implArith.cosine(context, [args]) */}}
+        {{ if $eMethod.Returns }}return{{ end }} this.impl{{ $eMethod.IfaceName }}.{{ $eMethod.Name }}(context{{ $eMethod.CallingArgsLeadingComma }});
     }
     @Override
-    {{ $eMethod.AccessModifier }} {{ $eMethod.RetType }} {{ $eMethod.Name }}(final io.v.v23.context.VContext context{{ $eMethod.DeclarationArgs }}, io.v.v23.Options vOpts) throws io.v.v23.verror.VException {
-        {{/* e.g. return this.stubArith.cosine(context, [args], options) */}}
-        {{ if $eMethod.Returns }}return{{ end }}  this.{{ $eMethod.LocalStubVarName }}.{{ $eMethod.Name }}(context{{ $eMethod.CallingArgsLeadingComma }}, vOpts);
+    public {{ $eMethod.RetType }} {{ $eMethod.Name }}(final io.v.v23.context.VContext context{{ $eMethod.DeclarationArgs }}, io.v.v23.Options vOpts) throws io.v.v23.verror.VException {
+        {{/* e.g. return this.implArith.cosine(context, [args], options) */}}
+        {{ if $eMethod.Returns }}return{{ end }}  this.impl{{ $eMethod.IfaceName }}.{{ $eMethod.Name }}(context{{ $eMethod.CallingArgsLeadingComma }}, vOpts);
     }
 {{ end }}
 
 }
 `
 
-type clientStubMethodOutArg struct {
+type clientImplMethodOutArg struct {
 	FieldName string
 	Type      string
 }
 
-type clientStubMethod struct {
-	AccessModifier          string
+type clientImplMethod struct {
 	CallingArgs             string
 	CallingArgTypes         string
 	CallingArgsLeadingComma string
@@ -154,7 +165,7 @@
 	MultipleReturn          bool
 	Name                    string
 	NotStreaming            bool
-	OutArgs                 []clientStubMethodOutArg
+	OutArgs                 []clientImplMethodOutArg
 	RecvType                string
 	RetType                 string
 	Returns                 bool
@@ -162,23 +173,22 @@
 	ServiceName             string
 }
 
-type clientStubEmbedMethod struct {
-	AccessModifier          string
+type clientImplEmbedMethod struct {
 	CallingArgsLeadingComma string
 	DeclarationArgs         string
-	LocalStubVarName        string
+	IfaceName               string
 	Name                    string
 	RetType                 string
 	Returns                 bool
 }
 
-type clientStubEmbed struct {
-	StubClassName    string
-	LocalStubVarName string
+type clientImplEmbed struct {
+	Name     string
+	FullName string
 }
 
-func processClientStubMethod(iface *compile.Interface, method *compile.Method, env *compile.Env) clientStubMethod {
-	outArgs := make([]clientStubMethodOutArg, len(method.OutArgs))
+func processClientImplMethod(iface *compile.Interface, method *compile.Method, env *compile.Env) clientImplMethod {
+	outArgs := make([]clientImplMethodOutArg, len(method.OutArgs))
 	for i := 0; i < len(method.OutArgs); i++ {
 		if method.OutArgs[i].Name != "" {
 			outArgs[i].FieldName = vdlutil.FirstRuneToLower(method.OutArgs[i].Name)
@@ -187,8 +197,7 @@
 		}
 		outArgs[i].Type = javaType(method.OutArgs[i].Type, true, env)
 	}
-	return clientStubMethod{
-		AccessModifier:          accessModifierForName(method.Name),
+	return clientImplMethod{
 		CallingArgs:             javaCallingArgStr(method.InArgs, false),
 		CallingArgTypes:         javaCallingArgTypeStr(method.InArgs, env),
 		CallingArgsLeadingComma: javaCallingArgStr(method.InArgs, true),
@@ -207,66 +216,61 @@
 	}
 }
 
-func processClientStubEmbedMethod(iface *compile.Interface, embedMethod *compile.Method, env *compile.Env) clientStubEmbedMethod {
-	return clientStubEmbedMethod{
-		AccessModifier:          accessModifierForName(embedMethod.Name),
+func processClientImplEmbedMethod(iface *compile.Interface, embedMethod *compile.Method, env *compile.Env) clientImplEmbedMethod {
+	return clientImplEmbedMethod{
 		CallingArgsLeadingComma: javaCallingArgStr(embedMethod.InArgs, true),
 		DeclarationArgs:         javaDeclarationArgStr(embedMethod.InArgs, env, true),
-		LocalStubVarName:        vdlutil.FirstRuneToLower(iface.Name) + "ClientStub",
+		IfaceName:               vdlutil.FirstRuneToUpper(iface.Name),
 		Name:                    vdlutil.FirstRuneToLower(embedMethod.Name),
 		RetType:                 clientInterfaceOutArg(iface, embedMethod, env),
 		Returns:                 len(embedMethod.OutArgs) >= 1 || isStreamingMethod(embedMethod),
 	}
 }
 
-// genJavaClientStubFile generates a client stub for the specified interface.
-func genJavaClientStubFile(iface *compile.Interface, env *compile.Env) JavaFileInfo {
-	embeds := []clientStubEmbed{}
+// genJavaClientImplFile generates a client impl for the specified interface.
+func genJavaClientImplFile(iface *compile.Interface, env *compile.Env) JavaFileInfo {
+	embeds := []clientImplEmbed{}
 	for _, embed := range allEmbeddedIfaces(iface) {
-		embeds = append(embeds, clientStubEmbed{
-			LocalStubVarName: vdlutil.FirstRuneToLower(embed.Name) + "ClientStub",
-			StubClassName:    javaPath(javaGenPkgPath(path.Join(embed.File.Package.GenPath, vdlutil.FirstRuneToUpper(embed.Name)+"ClientStub"))),
+		embeds = append(embeds, clientImplEmbed{
+			Name:     vdlutil.FirstRuneToUpper(embed.Name),
+			FullName: javaPath(javaGenPkgPath(path.Join(embed.File.Package.GenPath, vdlutil.FirstRuneToUpper(embed.Name)))),
 		})
 	}
-	embedMethods := []clientStubEmbedMethod{}
+	embedMethods := []clientImplEmbedMethod{}
 	for _, embedMao := range dedupedEmbeddedMethodAndOrigins(iface) {
-		embedMethods = append(embedMethods, processClientStubEmbedMethod(embedMao.Origin, embedMao.Method, env))
+		embedMethods = append(embedMethods, processClientImplEmbedMethod(embedMao.Origin, embedMao.Method, env))
 	}
-	methods := make([]clientStubMethod, len(iface.Methods))
+	methods := make([]clientImplMethod, len(iface.Methods))
 	for i, method := range iface.Methods {
-		methods[i] = processClientStubMethod(iface, method, env)
+		methods[i] = processClientImplMethod(iface, method, env)
 	}
 	javaServiceName := vdlutil.FirstRuneToUpper(iface.Name)
 	data := struct {
-		FileDoc          string
-		AccessModifier   string
-		EmbedMethods     []clientStubEmbedMethod
-		Embeds           []clientStubEmbed
-		FullServiceName  string
-		Methods          []clientStubMethod
-		PackagePath      string
-		ServiceName      string
-		Source           string
-		VDLIfacePathName string
+		FileDoc         string
+		EmbedMethods    []clientImplEmbedMethod
+		Embeds          []clientImplEmbed
+		FullServiceName string
+		Methods         []clientImplMethod
+		PackagePath     string
+		ServiceName     string
+		Source          string
 	}{
-		FileDoc:          iface.File.Package.FileDoc,
-		AccessModifier:   accessModifierForName(iface.Name),
-		EmbedMethods:     embedMethods,
-		Embeds:           embeds,
-		FullServiceName:  javaPath(interfaceFullyQualifiedName(iface)),
-		Methods:          methods,
-		PackagePath:      javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
-		ServiceName:      javaServiceName,
-		Source:           iface.File.BaseName,
-		VDLIfacePathName: path.Join(iface.File.Package.GenPath, iface.Name+"ClientMethods"),
+		FileDoc:         iface.File.Package.FileDoc,
+		EmbedMethods:    embedMethods,
+		Embeds:          embeds,
+		FullServiceName: javaPath(interfaceFullyQualifiedName(iface)),
+		Methods:         methods,
+		PackagePath:     javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
+		ServiceName:     javaServiceName,
+		Source:          iface.File.BaseName,
 	}
 	var buf bytes.Buffer
-	err := parseTmpl("client stub", clientStubTmpl).Execute(&buf, data)
+	err := parseTmpl("client impl", clientImplTmpl).Execute(&buf, data)
 	if err != nil {
-		log.Fatalf("vdl: couldn't execute client stub template: %v", err)
+		log.Fatalf("vdl: couldn't execute client impl template: %v", err)
 	}
 	return JavaFileInfo{
-		Name: javaServiceName + "ClientStub.java",
+		Name: javaServiceName + "ClientImpl.java",
 		Data: buf.Bytes(),
 	}
 }
diff --git a/lib/vdl/codegen/java/file_client_interface.go b/lib/vdl/codegen/java/file_client_interface.go
index 229dbfa..96c97f7 100644
--- a/lib/vdl/codegen/java/file_client_interface.go
+++ b/lib/vdl/codegen/java/file_client_interface.go
@@ -23,6 +23,9 @@
 {{ range $method := .Methods }}
     {{/* If this method has multiple return arguments, generate the class. */}}
     {{ if $method.IsMultipleRet }}
+    /**
+     * Multi-return value for method {@link #{{$method.Name}}}.
+     */
     @io.v.v23.vdl.MultiReturn
     public static class {{ $method.UppercaseMethodName }}Out {
         {{ range $retArg := $method.RetArgs }}
@@ -85,7 +88,7 @@
 	}
 	return clientInterfaceMethod{
 		Args:                javaDeclarationArgStr(method.InArgs, env, true),
-		Doc:                 method.Doc,
+		Doc:                 javaDoc(method.Doc, method.DocSuffix),
 		Name:                vdlutil.FirstRuneToLower(method.Name),
 		IsMultipleRet:       len(retArgs) > 1,
 		RetArgs:             retArgs,
@@ -115,7 +118,7 @@
 		Extends:     javaClientExtendsStr(iface.Embeds),
 		Methods:     methods,
 		PackagePath: javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
-		ServiceDoc:  javaDoc(iface.Doc),
+		ServiceDoc:  javaDoc(iface.Doc, iface.DocSuffix),
 		ServiceName: javaServiceName,
 		Source:      iface.File.BaseName,
 	}
diff --git a/lib/vdl/codegen/java/file_complex.go b/lib/vdl/codegen/java/file_complex.go
index 14b1b89..092bfe1 100644
--- a/lib/vdl/codegen/java/file_complex.go
+++ b/lib/vdl/codegen/java/file_complex.go
@@ -17,24 +17,40 @@
 // Source: {{.Source}}
 package {{.PackagePath}};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends {{.VdlComplex}} {
     private static final long serialVersionUID = 1L;
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given real and imaginary parts.
+     *
+     * @param real real part
+     * @param imag imaginary part
+     */
     public {{.Name}}({{.ValueType}} real, {{.ValueType}} imag) {
         super(VDL_TYPE, real, imag);
     }
 
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given real part and a zero imaginary
+     * part.
+     *
+     * @param real real part
+     */
     public {{.Name}}({{.ValueType}} real) {
         this(real, 0);
     }
 
+    /**
+     * Creates a new zero-value instance of {@link {{.Name}}}.
+     */
     public {{.Name}}() {
         this(0, 0);
     }
@@ -54,9 +70,9 @@
 	}
 	name, access := javaTypeName(tdef, env)
 	data := struct {
-		FileDoc        string
 		AccessModifier string
 		Doc            string
+		FileDoc        string
 		Name           string
 		PackagePath    string
 		Source         string
@@ -65,9 +81,9 @@
 		VdlTypeName    string
 		VdlTypeString  string
 	}{
-		FileDoc:        tdef.File.Package.FileDoc,
 		AccessModifier: access,
-		Doc:            javaDocInComment(tdef.Doc),
+		Doc:            javaDoc(tdef.Doc, tdef.DocSuffix),
+		FileDoc:        tdef.File.Package.FileDoc,
 		Name:           name,
 		PackagePath:    javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
 		Source:         tdef.File.BaseName,
diff --git a/lib/vdl/codegen/java/file_constants.go b/lib/vdl/codegen/java/file_constants.go
index 2ea6a90..9e892a6 100644
--- a/lib/vdl/codegen/java/file_constants.go
+++ b/lib/vdl/codegen/java/file_constants.go
@@ -16,17 +16,20 @@
 // Source(s): {{ .Source }}
 package {{ .PackagePath }};
 
-
+/**
+ * Constants defined in all VDL files in this package.
+ */
 public final class {{ .ClassName }} {
     {{ range $file := .Files }}
 
     /* The following constants originate in file: {{ $file.Name }} */
-    {{/*Constants*/}}
     {{ range $const := $file.Consts }}
     {{ $const.Doc }}
     {{ $const.AccessModifier }} static final {{ $const.Type }} {{ $const.Name }} = {{ $const.Value }};
     {{ end }} {{/* end range $file.Consts */}}
     {{ end }} {{/* range .Files */}}
+
+    private {{ .ClassName }}() {}
 }
 `
 
@@ -66,7 +69,7 @@
 		consts := make([]constConst, len(file.ConstDefs))
 		for j, cnst := range file.ConstDefs {
 			consts[j].AccessModifier = accessModifierForName(cnst.Name)
-			consts[j].Doc = javaDoc(cnst.Doc)
+			consts[j].Doc = javaDoc(cnst.Doc, cnst.DocSuffix)
 			consts[j].Type = javaType(cnst.Value.Type(), false, env)
 			consts[j].Name = vdlutil.ToConstCase(cnst.Name)
 			consts[j].Value = javaConstVal(cnst.Value, env)
@@ -76,17 +79,17 @@
 	}
 
 	data := struct {
-		FileDoc     string
 		ClassName   string
-		Source      string
-		PackagePath string
+		FileDoc     string
 		Files       []constFile
+		PackagePath string
+		Source      string
 	}{
-		FileDoc:     pkg.FileDoc,
 		ClassName:   className,
-		Source:      javaFileNames(pkg.Files),
-		PackagePath: javaPath(javaGenPkgPath(pkg.GenPath)),
+		FileDoc:     pkg.FileDoc,
 		Files:       files,
+		PackagePath: javaPath(javaGenPkgPath(pkg.GenPath)),
+		Source:      javaFileNames(pkg.Files),
 	}
 	var buf bytes.Buffer
 	err := parseTmpl("const", constTmpl).Execute(&buf, data)
diff --git a/lib/vdl/codegen/java/file_enum.go b/lib/vdl/codegen/java/file_enum.go
index f69bacb..9b80380 100644
--- a/lib/vdl/codegen/java/file_enum.go
+++ b/lib/vdl/codegen/java/file_enum.go
@@ -15,22 +15,24 @@
 // Source: {{.Source}}
 package {{.PackagePath}};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends io.v.v23.vdl.VdlEnum {
     {{ range $index, $label := .EnumLabels }}
-        @io.v.v23.vdl.GeneratedFromVdl(name = "{{$label}}", index = {{$index}})
-        public static final {{$.Name}} {{$label}};
+        @io.v.v23.vdl.GeneratedFromVdl(name = "{{$label.Name}}", index = {{$index}})
+        {{ $label.Doc }}
+        public static final {{$.Name}} {{$label.Name}};
     {{ end }}
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
     static {
         {{ range $label := .EnumLabels }}
-            {{$label}} = new {{$.Name}}("{{$label}}");
+            {{$label.Name}} = new {{$.Name}}("{{$label.Name}}");
         {{ end }}
     }
 
@@ -38,10 +40,13 @@
         super(VDL_TYPE, name);
     }
 
+    /**
+     * Returns the enum with the given name.
+     */
     public static {{.Name}} valueOf(String name) {
         {{ range $label := .EnumLabels }}
-            if ("{{$label}}".equals(name)) {
-                return {{$label}};
+            if ("{{$label.Name}}".equals(name)) {
+                return {{$label.Name}};
             }
         {{ end }}
         throw new java.lang.IllegalArgumentException();
@@ -49,28 +54,36 @@
 }
 `
 
+type enumLabel struct {
+	Doc  string
+	Name string
+}
+
 // genJavaEnumFile generates the Java class file for the provided user-defined enum type.
 func genJavaEnumFile(tdef *compile.TypeDef, env *compile.Env) JavaFileInfo {
-	labels := make([]string, tdef.Type.NumEnumLabel())
+	labels := make([]enumLabel, tdef.Type.NumEnumLabel())
 	for i := 0; i < tdef.Type.NumEnumLabel(); i++ {
-		labels[i] = tdef.Type.EnumLabel(i)
+		labels[i] = enumLabel{
+			Doc:  javaDoc(tdef.LabelDoc[i], tdef.LabelDocSuffix[i]),
+			Name: tdef.Type.EnumLabel(i),
+		}
 	}
 	name, access := javaTypeName(tdef, env)
 	data := struct {
-		FileDoc        string
 		AccessModifier string
-		EnumLabels     []string
 		Doc            string
+		EnumLabels     []enumLabel
+		FileDoc        string
 		Name           string
 		PackagePath    string
 		Source         string
 		VdlTypeName    string
 		VdlTypeString  string
 	}{
-		FileDoc:        tdef.File.Package.FileDoc,
 		AccessModifier: access,
+		Doc:            javaDoc(tdef.Doc, tdef.DocSuffix),
 		EnumLabels:     labels,
-		Doc:            javaDocInComment(tdef.Doc),
+		FileDoc:        tdef.File.Package.FileDoc,
 		Name:           name,
 		PackagePath:    javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
 		Source:         tdef.File.BaseName,
diff --git a/lib/vdl/codegen/java/file_errors.go b/lib/vdl/codegen/java/file_errors.go
index ac2c49e..7c0272c 100644
--- a/lib/vdl/codegen/java/file_errors.go
+++ b/lib/vdl/codegen/java/file_errors.go
@@ -16,7 +16,9 @@
 // Source(s): {{ .Source }}
 package {{ .PackagePath }};
 
-
+/**
+ * Errors defined in all VDL files in this package.
+ */
 public final class {{ .ClassName }} {
     {{ range $file := .Files }}
 
@@ -44,15 +46,17 @@
     /* The following error creator methods originate in file: {{ $file.Name }} */
     {{ range $error := $file.Errors }}
     /**
-     * Creates an error with {@code {{ $error.Name }}} identifier.
+     * Creates an error with the {@link #{{ $error.Name }}} identifier.
      */
-    public static io.v.v23.verror.VException {{ $error.MethodName }}(io.v.v23.context.VContext _ctx{{ $error.MethodArgs}}) {
+    {{ $error.AccessModifier }} static io.v.v23.verror.VException {{ $error.MethodName }}(io.v.v23.context.VContext _ctx{{ $error.MethodArgs}}) {
         final java.lang.Object[] _params = new java.lang.Object[] { {{ $error.Params }} };
         final java.lang.reflect.Type[] _paramTypes = new java.lang.reflect.Type[]{ {{ $error.ParamTypes }} };
         return new io.v.v23.verror.VException({{ $error.Name }}, _ctx, _paramTypes, _params);
     }
     {{ end }} {{/* range $file.Errors */}}
     {{ end }} {{/* range .Files */}}
+
+    private {{ .ClassName }}() {}
 }
 `
 
@@ -108,7 +112,7 @@
 				formats[k].Fmt = format.Fmt
 			}
 			errors[j].AccessModifier = accessModifierForName(err.Name)
-			errors[j].Doc = javaDoc(err.Doc)
+			errors[j].Doc = javaDoc(err.Doc, err.DocSuffix)
 			errors[j].Name = vdlutil.ToConstCase(err.Name)
 			errors[j].ID = err.ID
 			errors[j].ActionName = vdlutil.ToConstCase(err.RetryCode.String())
@@ -124,14 +128,14 @@
 	}
 
 	data := struct {
-		FileDoc     string
 		ClassName   string
+		FileDoc     string
 		Source      string
 		PackagePath string
 		Files       []errorFile
 	}{
-		FileDoc:     pkg.FileDoc,
 		ClassName:   className,
+		FileDoc:     pkg.FileDoc,
 		Source:      javaFileNames(pkg.Files),
 		PackagePath: javaPath(javaGenPkgPath(pkg.GenPath)),
 		Files:       files,
diff --git a/lib/vdl/codegen/java/file_list.go b/lib/vdl/codegen/java/file_list.go
index 327469f..4e6cf7e 100644
--- a/lib/vdl/codegen/java/file_list.go
+++ b/lib/vdl/codegen/java/file_list.go
@@ -15,20 +15,29 @@
 // Source: {{.SourceFile}}
 package {{.Package}};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends io.v.v23.vdl.VdlList<{{.ElemType}}> {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given underlying value.
+     *
+     * @param impl underlying value
+     */
     public {{.Name}}(java.util.List<{{.ElemType}}> impl) {
         super(VDL_TYPE, impl);
     }
 
+    /**
+     * Creates a new empty instance of {@link {{.Name}}}.
+     */
     public {{.Name}}() {
         this(new java.util.ArrayList<{{.ElemType}}>());
     }
@@ -39,20 +48,20 @@
 func genJavaListFile(tdef *compile.TypeDef, env *compile.Env) JavaFileInfo {
 	name, access := javaTypeName(tdef, env)
 	data := struct {
-		FileDoc        string
 		AccessModifier string
 		Doc            string
 		ElemType       string
+		FileDoc        string
 		Name           string
 		Package        string
 		SourceFile     string
 		VdlTypeName    string
 		VdlTypeString  string
 	}{
-		FileDoc:        tdef.File.Package.FileDoc,
 		AccessModifier: access,
-		Doc:            javaDocInComment(tdef.Doc),
+		Doc:            javaDoc(tdef.Doc, tdef.DocSuffix),
 		ElemType:       javaType(tdef.Type.Elem(), true, env),
+		FileDoc:        tdef.File.Package.FileDoc,
 		Name:           name,
 		Package:        javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
 		SourceFile:     tdef.File.BaseName,
diff --git a/lib/vdl/codegen/java/file_map.go b/lib/vdl/codegen/java/file_map.go
index 255f4bb..2cfe3fe 100644
--- a/lib/vdl/codegen/java/file_map.go
+++ b/lib/vdl/codegen/java/file_map.go
@@ -16,20 +16,29 @@
 
 package {{.Package}};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends io.v.v23.vdl.VdlMap<{{.KeyType}}, {{.ElemType}}> {
     private static final long serialVersionUID = 1L;
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given underlying value.
+     *
+     * @param impl underlying value
+     */
     public {{.Name}}(java.util.Map<{{.KeyType}}, {{.ElemType}}> impl) {
         super(VDL_TYPE, impl);
     }
 
+    /**
+     * Creates a new empty instance of {@link {{.Name}}}.
+     */
     public {{.Name}}() {
         this(new java.util.HashMap<{{.KeyType}}, {{.ElemType}}>());
     }
@@ -40,10 +49,10 @@
 func genJavaMapFile(tdef *compile.TypeDef, env *compile.Env) JavaFileInfo {
 	name, access := javaTypeName(tdef, env)
 	data := struct {
-		FileDoc        string
 		AccessModifier string
 		Doc            string
 		ElemType       string
+		FileDoc        string
 		KeyType        string
 		Name           string
 		Package        string
@@ -51,10 +60,10 @@
 		VdlTypeName    string
 		VdlTypeString  string
 	}{
-		FileDoc:        tdef.File.Package.FileDoc,
 		AccessModifier: access,
-		Doc:            javaDocInComment(tdef.Doc),
+		Doc:            javaDoc(tdef.Doc, tdef.DocSuffix),
 		ElemType:       javaType(tdef.Type.Elem(), true, env),
+		FileDoc:        tdef.File.Package.FileDoc,
 		KeyType:        javaType(tdef.Type.Key(), true, env),
 		Name:           name,
 		Package:        javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
diff --git a/lib/vdl/codegen/java/file_package_info.go b/lib/vdl/codegen/java/file_package_info.go
index 2e94276..a845a78 100644
--- a/lib/vdl/codegen/java/file_package_info.go
+++ b/lib/vdl/codegen/java/file_package_info.go
@@ -31,15 +31,15 @@
 			generated = true
 
 			data := struct {
-				FileDoc     string
-				Source      string
-				PackagePath string
 				Doc         string
+				FileDoc     string
+				PackagePath string
+				Source      string
 			}{
+				Doc:         javaDoc(file.PackageDef.Doc, file.PackageDef.DocSuffix),
 				FileDoc:     pkg.FileDoc,
-				Source:      javaFileNames(pkg.Files),
 				PackagePath: javaPath(javaGenPkgPath(pkg.GenPath)),
-				Doc:         javaDoc(file.PackageDef.Doc),
+				Source:      javaFileNames(pkg.Files),
 			}
 			var buf bytes.Buffer
 			err := parseTmpl("package", packageTmpl).Execute(&buf, data)
diff --git a/lib/vdl/codegen/java/file_primitive.go b/lib/vdl/codegen/java/file_primitive.go
index c94760e..c624e5c 100644
--- a/lib/vdl/codegen/java/file_primitive.go
+++ b/lib/vdl/codegen/java/file_primitive.go
@@ -13,23 +13,32 @@
 )
 
 const primitiveTmpl = header + `
-// Source: {{.Source}}
-package {{.PackagePath}};
+// Source: {{ .Source }}
+package {{ .PackagePath }};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends {{.VdlType}} {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given value.
+     *
+     * @param value value
+     */
     public {{.Name}}({{.ConstructorType}} value) {
         super(VDL_TYPE, value);
     }
 
+    /**
+     * Creates a new zero-value instance of {@link {{.Name}}}.
+     */
     public {{.Name}}() {
         super(VDL_TYPE);
     }
@@ -72,25 +81,25 @@
 func genJavaPrimitiveFile(tdef *compile.TypeDef, env *compile.Env) JavaFileInfo {
 	name, access := javaTypeName(tdef, env)
 	data := struct {
-		FileDoc                  string
 		AccessModifier           string
+		ConstructorType          string
 		Doc                      string
+		FileDoc                  string
 		Name                     string
 		PackagePath              string
 		Source                   string
-		ConstructorType          string
 		TypeAdapterDelegateClass string
 		VdlType                  string
 		VdlTypeName              string
 		VdlTypeString            string
 	}{
-		FileDoc:                  tdef.File.Package.FileDoc,
-		AccessModifier:           access,
-		Doc:                      javaDocInComment(tdef.Doc),
-		Name:                     name,
-		PackagePath:              javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
-		Source:                   tdef.File.BaseName,
-		ConstructorType:          javaConstructorType(tdef.Type),
+		AccessModifier:  access,
+		Doc:             javaDoc(tdef.Doc, tdef.DocSuffix),
+		ConstructorType: javaConstructorType(tdef.Type),
+		FileDoc:         tdef.File.Package.FileDoc,
+		Name:            name,
+		PackagePath:     javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
+		Source:          tdef.File.BaseName,
 		TypeAdapterDelegateClass: javaTypeAdapterDelegateClass(tdef.Type),
 		VdlType:                  javaVdlPrimitiveType(tdef.Type.Kind()),
 		VdlTypeName:              tdef.Type.Name(),
diff --git a/lib/vdl/codegen/java/file_server_interface.go b/lib/vdl/codegen/java/file_server_interface.go
index 4e50cbd..e4c7c7d 100644
--- a/lib/vdl/codegen/java/file_server_interface.go
+++ b/lib/vdl/codegen/java/file_server_interface.go
@@ -26,6 +26,9 @@
 {{ range $method := .Methods }}
     {{/* If this method has multiple return arguments, generate the class. */}}
     {{ if $method.IsMultipleRet }}
+    /**
+     * Multi-return value for method {@link #{{$method.Name}}}.
+     */
     @io.v.v23.vdl.MultiReturn
     public static class {{ $method.UppercaseMethodName }}Out {
         {{ range $retArg := $method.RetArgs }}
@@ -84,7 +87,7 @@
 
 	return serverInterfaceMethod{
 		Args:                args,
-		Doc:                 method.Doc,
+		Doc:                 javaDoc(method.Doc, method.DocSuffix),
 		Name:                vdlutil.FirstRuneToLower(method.Name),
 		IsMultipleRet:       len(retArgs) > 1,
 		RetArgs:             retArgs,
@@ -116,7 +119,7 @@
 		Extends:           javaServerExtendsStr(iface.Embeds),
 		Methods:           methods,
 		PackagePath:       javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
-		ServerDoc:         javaDoc(iface.Doc),
+		ServerDoc:         javaDoc(iface.Doc, iface.DocSuffix),
 		ServiceName:       javaServiceName,
 		ServerVDLPath:     path.Join(iface.File.Package.GenPath, iface.Name+"ServerMethods"),
 		ServerWrapperPath: javaPath(javaGenPkgPath(path.Join(iface.File.Package.GenPath, javaServiceName+"ServerWrapper"))),
diff --git a/lib/vdl/codegen/java/file_server_wrapper.go b/lib/vdl/codegen/java/file_server_wrapper.go
index 5043d6d..55faa59 100644
--- a/lib/vdl/codegen/java/file_server_wrapper.go
+++ b/lib/vdl/codegen/java/file_server_wrapper.go
@@ -18,21 +18,30 @@
 // Source(s):  {{ .Source }}
 package {{ .PackagePath }};
 
-{{ .AccessModifier }} final class {{ .ServiceName }}ServerWrapper {
-
+/**
+ * Wrapper for {@link {{ .ServiceName }}Server}.  This wrapper is used by
+ * {@link io.v.v23.rpc.ReflectInvoker} to indirectly invoke server methods.
+ */
+public final class {{ .ServiceName }}ServerWrapper {
     private final {{ .FullServiceName }}Server server;
 
 {{/* Define fields to hold each of the embedded server wrappers*/}}
 {{ range $embed := .Embeds }}
     {{/* e.g. private final com.somepackage.gen_impl.ArithStub stubArith; */}}
-    private final {{ $embed.WrapperClassName }} {{ $embed.LocalWrapperVarName }};
+    private final {{ $embed.FullName }}ServerWrapper wrapper{{ $embed.Name }};
     {{ end }}
 
+    /**
+     * Creates a new {@link {{ .ServiceName }}ServerWrapper} to invoke the methods of the
+     * provided server.
+     *
+     * @param server server whose methods are to be invoked
+     */
     public {{ .ServiceName }}ServerWrapper(final {{ .FullServiceName }}Server server) {
         this.server = server;
         {{/* Initialize the embeded server wrappers */}}
         {{ range $embed := .Embeds }}
-        this.{{ $embed.LocalWrapperVarName }} = new {{ $embed.WrapperClassName }}(server);
+        this.wrapper{{ $embed.Name }} = new {{ $embed.FullName }}ServerWrapper(server);
         {{ end }}
     }
 
@@ -71,8 +80,10 @@
     }
 
     /**
-     * Returns all tags associated with the provided method or null if the method isn't implemented
-     * by this server.
+     * Returns all tags associated with the provided method or {@code null} if the method isn't
+     * implemented by this server.
+     *
+     * @param method method whose tags are to be returned
      */
     @SuppressWarnings("unused")
     public io.v.v23.vdl.VdlValue[] getMethodTags(final java.lang.String method) throws io.v.v23.verror.VException {
@@ -89,7 +100,7 @@
         {{ end }}
         {{ range $embed := .Embeds }}
         {
-            final io.v.v23.vdl.VdlValue[] tags = this.{{ $embed.LocalWrapperVarName }}.getMethodTags(method);
+            final io.v.v23.vdl.VdlValue[] tags = this.wrapper{{ $embed.Name }}.getMethodTags(method);
             if (tags != null) {
                 return tags;
             }
@@ -100,7 +111,8 @@
 
      {{/* Iterate over methods defined directly in the body of this server */}}
     {{ range $method := .Methods }}
-    {{ $method.AccessModifier }} {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext ctx, final io.v.v23.rpc.StreamServerCall call{{ $method.DeclarationArgs }}) throws io.v.v23.verror.VException {
+    {{ $method.JavaDoc }}
+    public {{ $method.RetType }} {{ $method.Name }}(final io.v.v23.context.VContext ctx, final io.v.v23.rpc.StreamServerCall call{{ $method.DeclarationArgs }}) throws io.v.v23.verror.VException {
         {{ if $method.IsStreaming }}
         final io.v.v23.vdl.Stream<{{ $method.SendType }}, {{ $method.RecvType }}> _stream = new io.v.v23.vdl.Stream<{{ $method.SendType }}, {{ $method.RecvType }}>() {
             @Override
@@ -126,9 +138,10 @@
 
 {{/* Iterate over methods from embeded servers and generate code to delegate the work */}}
 {{ range $eMethod := .EmbedMethods }}
-    {{ $eMethod.AccessModifier }} {{ $eMethod.RetType }} {{ $eMethod.Name }}(final io.v.v23.context.VContext ctx, final io.v.v23.rpc.StreamServerCall call{{ $eMethod.DeclarationArgs }}) throws io.v.v23.verror.VException {
+    {{ $eMethod.JavaDoc }}
+    public {{ $eMethod.RetType }} {{ $eMethod.Name }}(final io.v.v23.context.VContext ctx, final io.v.v23.rpc.StreamServerCall call{{ $eMethod.DeclarationArgs }}) throws io.v.v23.verror.VException {
         {{/* e.g. return this.stubArith.cosine(ctx, call, [args], options) */}}
-        {{ if $eMethod.Returns }}return{{ end }}  this.{{ $eMethod.LocalWrapperVarName }}.{{ $eMethod.Name }}(ctx, call{{ $eMethod.CallingArgs }});
+        {{ if $eMethod.Returns }}return{{ end }}  this.wrapper{{ $eMethod.IfaceName }}.{{ $eMethod.Name }}(ctx, call{{ $eMethod.CallingArgs }});
     }
 {{ end }} {{/* end range .EmbedMethods */}}
 
@@ -136,34 +149,35 @@
 `
 
 type serverWrapperMethod struct {
-	AccessModifier  string
 	CallingArgs     string
 	CallingArgTypes []string
 	DeclarationArgs string
+	Doc             string
 	IsStreaming     bool
+	JavaDoc         string
 	Name            string
 	RecvType        string
 	RetType         string
 	RetJavaTypes    []string
 	Returns         bool
 	SendType        string
-	Doc             string
 	Tags            []methodTag
 }
 
 type serverWrapperEmbedMethod struct {
-	AccessModifier      string
-	CallingArgs         string
-	DeclarationArgs     string
-	LocalWrapperVarName string
-	Name                string
-	RetType             string
-	Returns             bool
+	CallingArgs     string
+	DeclarationArgs string
+	Doc             string
+	IfaceName       string
+	JavaDoc         string
+	Name            string
+	RetType         string
+	Returns         bool
 }
 
 type serverWrapperEmbed struct {
-	LocalWrapperVarName string
-	WrapperClassName    string
+	Name     string
+	FullName string
 }
 
 type methodTag struct {
@@ -188,31 +202,31 @@
 		retArgTypes[i] = javaReflectType(arg.Type, env)
 	}
 	return serverWrapperMethod{
-		AccessModifier:  accessModifierForName(method.Name),
 		CallingArgs:     javaCallingArgStr(method.InArgs, true),
 		CallingArgTypes: callArgTypes,
 		DeclarationArgs: javaDeclarationArgStr(method.InArgs, env, true),
+		Doc:             toJavaString(method.Doc),
 		IsStreaming:     isStreamingMethod(method),
+		JavaDoc:         javaDoc(method.Doc, method.DocSuffix),
 		Name:            vdlutil.FirstRuneToLower(method.Name),
 		RecvType:        javaType(method.InStream, true, env),
 		RetType:         serverInterfaceOutArg(iface, method, env),
 		RetJavaTypes:    retArgTypes,
 		Returns:         len(method.OutArgs) >= 1,
 		SendType:        javaType(method.OutStream, true, env),
-		Doc:             toJavaString(method.NamePos.Doc),
 		Tags:            tags,
 	}
 }
 
 func processServerWrapperEmbedMethod(iface *compile.Interface, embedMethod *compile.Method, env *compile.Env) serverWrapperEmbedMethod {
 	return serverWrapperEmbedMethod{
-		AccessModifier:      accessModifierForName(embedMethod.Name),
-		CallingArgs:         javaCallingArgStr(embedMethod.InArgs, true),
-		DeclarationArgs:     javaDeclarationArgStr(embedMethod.InArgs, env, true),
-		LocalWrapperVarName: vdlutil.FirstRuneToLower(iface.Name) + "Wrapper",
-		Name:                vdlutil.FirstRuneToLower(embedMethod.Name),
-		RetType:             serverInterfaceOutArg(iface, embedMethod, env),
-		Returns:             len(embedMethod.OutArgs) >= 1,
+		CallingArgs:     javaCallingArgStr(embedMethod.InArgs, true),
+		DeclarationArgs: javaDeclarationArgStr(embedMethod.InArgs, env, true),
+		IfaceName:       vdlutil.FirstRuneToUpper(iface.Name),
+		JavaDoc:         javaDoc(embedMethod.Doc, embedMethod.DocSuffix),
+		Name:            vdlutil.FirstRuneToLower(embedMethod.Name),
+		RetType:         serverInterfaceOutArg(iface, embedMethod, env),
+		Returns:         len(embedMethod.OutArgs) >= 1,
 	}
 }
 
@@ -222,8 +236,8 @@
 	embeds := []serverWrapperEmbed{}
 	for _, embed := range allEmbeddedIfaces(iface) {
 		embeds = append(embeds, serverWrapperEmbed{
-			WrapperClassName:    javaPath(javaGenPkgPath(path.Join(embed.File.Package.GenPath, vdlutil.FirstRuneToUpper(embed.Name+"ServerWrapper")))),
-			LocalWrapperVarName: vdlutil.FirstRuneToLower(embed.Name) + "Wrapper",
+			Name:     vdlutil.FirstRuneToUpper(embed.Name),
+			FullName: javaPath(javaGenPkgPath(path.Join(embed.File.Package.GenPath, vdlutil.FirstRuneToUpper(embed.Name)))),
 		})
 	}
 	methodTags := make(map[string][]methodTag)
@@ -245,7 +259,6 @@
 	javaServiceName := vdlutil.FirstRuneToUpper(iface.Name)
 	data := struct {
 		FileDoc         string
-		AccessModifier  string
 		EmbedMethods    []serverWrapperEmbedMethod
 		Embeds          []serverWrapperEmbed
 		FullServiceName string
@@ -257,7 +270,6 @@
 		Doc             string
 	}{
 		FileDoc:         iface.File.Package.FileDoc,
-		AccessModifier:  accessModifierForName(iface.Name),
 		EmbedMethods:    embedMethods,
 		Embeds:          embeds,
 		FullServiceName: javaPath(interfaceFullyQualifiedName(iface)),
diff --git a/lib/vdl/codegen/java/file_set.go b/lib/vdl/codegen/java/file_set.go
index cd703c1..175d7d7 100644
--- a/lib/vdl/codegen/java/file_set.go
+++ b/lib/vdl/codegen/java/file_set.go
@@ -16,20 +16,29 @@
 
 package {{.Package}};
 
-/**
- * {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends io.v.v23.vdl.VdlSet<{{.KeyType}}> {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
+    /**
+     * Creates a new instance of {@link {{.Name}}} with the given underlying value.
+     *
+     * @param impl underlying value
+     */
     public {{.Name}}(java.util.Set<{{.KeyType}}> impl) {
         super(VDL_TYPE, impl);
     }
 
+    /**
+     * Creates a new zero-value instance of {@link {{.Name}}}.
+     */
     public {{.Name}}() {
         this(new java.util.HashSet<{{.KeyType}}>());
     }
@@ -40,9 +49,9 @@
 func genJavaSetFile(tdef *compile.TypeDef, env *compile.Env) JavaFileInfo {
 	name, access := javaTypeName(tdef, env)
 	data := struct {
-		FileDoc        string
 		AccessModifier string
 		Doc            string
+		FileDoc        string
 		KeyType        string
 		Name           string
 		Package        string
@@ -50,9 +59,9 @@
 		VdlTypeName    string
 		VdlTypeString  string
 	}{
-		FileDoc:        tdef.File.Package.FileDoc,
 		AccessModifier: access,
-		Doc:            javaDocInComment(tdef.Doc),
+		Doc:            javaDoc(tdef.Doc, tdef.DocSuffix),
+		FileDoc:        tdef.File.Package.FileDoc,
 		KeyType:        javaType(tdef.Type.Key(), true, env),
 		Name:           name,
 		Package:        javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
diff --git a/lib/vdl/codegen/java/file_struct.go b/lib/vdl/codegen/java/file_struct.go
index f36c7ef..30bdf19 100644
--- a/lib/vdl/codegen/java/file_struct.go
+++ b/lib/vdl/codegen/java/file_struct.go
@@ -17,9 +17,7 @@
 // Source: {{.Source}}
 package {{.PackagePath}};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends io.v.v23.vdl.AbstractVdlStruct {
     private static final long serialVersionUID = 1L;
@@ -30,10 +28,16 @@
       private {{$field.Type}} {{$field.LowercaseName}};
     {{ end }}
 
+    /**
+     * Vdl type for {@link {{.Name}}}.
+     */
     public static final io.v.v23.vdl.VdlType VDL_TYPE =
             io.v.v23.vdl.Types.getVdlTypeFromReflect({{.Name}}.class);
 
     {{/* Constructors */}}
+    /**
+     * Creates a new zero-value instance of {@link {{.Name}}}.
+     */
     public {{.Name}}() {
         super(VDL_TYPE);
         {{ range $field := .Fields }}
@@ -42,6 +46,9 @@
     }
 
     {{ if .FieldsAsArgs }}
+    /**
+     * Creates a new instance of {@link {{ .Name }}} with the provided field values.
+     */
     public {{.Name}}({{ .FieldsAsArgs }}) {
         super(VDL_TYPE);
         {{ range $field := .Fields }}
@@ -52,10 +59,12 @@
 
     {{/* Getters and setters */}}
     {{ range $field := .Fields }}
+    {{ $field.Doc }}
     {{ $field.AccessModifier }} {{$field.Type}} get{{$field.Name}}() {
         return this.{{$field.LowercaseName}};
     }
 
+    {{ $field.Doc }}
     {{ $field.AccessModifier }} void set{{$field.Name}}({{$field.Type}} {{$field.LowercaseName}}) {
         this.{{$field.LowercaseName}} = {{$field.LowercaseName}};
     }
@@ -122,6 +131,7 @@
 type structDefinitionField struct {
 	AccessModifier      string
 	Class               string
+	Doc                 string
 	HashcodeComputation string
 	IsClass             bool
 	IsArray             bool
@@ -154,6 +164,7 @@
 		fields[i] = structDefinitionField{
 			AccessModifier:      accessModifierForName(fld.Name),
 			Class:               javaType(fld.Type, true, env),
+			Doc:                 javaDoc(tdef.FieldDoc[i], tdef.FieldDocSuffix[i]),
 			HashcodeComputation: javaHashCode(vdlutil.FirstRuneToLower(fld.Name), fld.Type, env),
 			IsClass:             isClass(fld.Type, env),
 			IsArray:             isJavaNativeArray(fld.Type, env),
@@ -179,7 +190,7 @@
 	}{
 		FileDoc:        tdef.File.Package.FileDoc,
 		AccessModifier: access,
-		Doc:            javaDocInComment(tdef.Doc),
+		Doc:            javaDoc(tdef.Doc, tdef.DocSuffix),
 		Fields:         fields,
 		FieldsAsArgs:   javaFieldArgStr(tdef.Type, env),
 		Name:           name,
diff --git a/lib/vdl/codegen/java/file_union.go b/lib/vdl/codegen/java/file_union.go
index f8a0ac2..085587f 100644
--- a/lib/vdl/codegen/java/file_union.go
+++ b/lib/vdl/codegen/java/file_union.go
@@ -15,14 +15,13 @@
 // Source: {{.Source}}
 package {{.PackagePath}};
 
-/**
- * type {{.Name}} {{.VdlTypeString}} {{.Doc}}
- **/
+{{ .Doc }}
 @io.v.v23.vdl.GeneratedFromVdl(name = "{{.VdlTypeName}}")
 {{ .AccessModifier }} class {{.Name}} extends io.v.v23.vdl.VdlUnion {
 	private static final long serialVersionUID = 1L;
 
     {{ range $index, $field := .Fields }}
+    {{ $field.Doc }}
     @io.v.v23.vdl.GeneratedFromVdl(name = "{{$field.Name}}", index = {{$index}})
     public static class {{$field.Name}} extends {{$.Name}} {
     	private static final long serialVersionUID = 1L;
@@ -60,6 +59,7 @@
 
 type unionDefinitionField struct {
 	Class               string
+	Doc                 string
 	HashcodeComputation string
 	Name                string
 	Type                string
@@ -73,6 +73,7 @@
 		fld := tdef.Type.Field(i)
 		fields[i] = unionDefinitionField{
 			Class:               javaType(fld.Type, true, env),
+			Doc:                 javaDoc(tdef.FieldDoc[i], tdef.FieldDocSuffix[i]),
 			HashcodeComputation: javaHashCode("elem", fld.Type, env),
 			Name:                fld.Name,
 			Type:                javaType(fld.Type, false, env),
@@ -93,7 +94,7 @@
 	}{
 		FileDoc:        tdef.File.Package.FileDoc,
 		AccessModifier: access,
-		Doc:            javaDocInComment(tdef.Doc),
+		Doc:            javaDoc(tdef.Doc, tdef.DocSuffix),
 		Fields:         fields,
 		Name:           name,
 		PackagePath:    javaPath(javaGenPkgPath(tdef.File.Package.GenPath)),
diff --git a/lib/vdl/codegen/java/generate.go b/lib/vdl/codegen/java/generate.go
index 008e2c1..da23e68 100644
--- a/lib/vdl/codegen/java/generate.go
+++ b/lib/vdl/codegen/java/generate.go
@@ -91,7 +91,7 @@
 		for _, iface := range file.Interfaces {
 			ret = append(ret, genJavaClientFactoryFile(iface, env))
 			ret = append(ret, genJavaClientInterfaceFile(iface, env)) // client interface
-			ret = append(ret, genJavaClientStubFile(iface, env))
+			ret = append(ret, genJavaClientImplFile(iface, env))
 			ret = append(ret, genJavaServerInterfaceFile(iface, env)) // server interface
 			ret = append(ret, genJavaServerWrapperFile(iface, env))
 		}
diff --git a/lib/vdl/codegen/java/util_doc.go b/lib/vdl/codegen/java/util_doc.go
index cce01f5..d84fb15 100644
--- a/lib/vdl/codegen/java/util_doc.go
+++ b/lib/vdl/codegen/java/util_doc.go
@@ -5,40 +5,38 @@
 package java
 
 import (
+	"bufio"
 	"strings"
 )
 
-// javaRawComment extracts a raw language-independent comment from a VDL comment.
-func javaRawComment(vdlComment string) string {
-	if vdlComment == "" {
+// javaDoc transforms the provided VDL doc and a doc suffix into the JavaDoc format.
+func javaDoc(doc, suffix string) string {
+	if doc == "" && suffix == "" {
 		return ""
 	}
-	comment := strings.Replace(vdlComment, "/**", "", -1)
-	comment = strings.Replace(comment, "/*", "", -1)
-	comment = strings.Replace(comment, "*/", "", -1)
-	comment = strings.Replace(comment, "//", "", -1)
-	comment = strings.Replace(comment, "\n *", "\n", -1)
-	splitComment := strings.Split(comment, "\n")
-	for i, _ := range splitComment {
-		splitComment[i] = strings.TrimSpace(splitComment[i])
+	if doc == "" {
+		doc = suffix
+	} else if suffix != "" {
+		doc = doc + "\n" + suffix
 	}
-	return strings.TrimSpace(strings.Join(splitComment, "\n"))
-}
-
-// javaDocInComment transforms a VDL comment to javadoc style, but without starting a new comment.
-// (i.e. this assumes that the output will be within a /**  */ comment).
-func javaDocInComment(vdlComment string) string {
-	if vdlComment == "" {
-		return ""
+	ret := "/**\n"
+	reader := bufio.NewReader(strings.NewReader(doc))
+	for {
+		line, err := reader.ReadString('\n')
+		line = strings.TrimSpace(line)
+		if strings.HasPrefix(line, "//") {
+			ret += " *"
+			if len(line[2:]) == 0 { // empty line
+				ret += "<p>"
+			} else {
+				ret += line[2:]
+			}
+			ret += "\n"
+		}
+		if err != nil {
+			break
+		}
 	}
-	return "\n * " + strings.Replace(javaRawComment(vdlComment), "\n", "\n * ", -1)
-}
-
-// javaDoc transforms the provided VDL comment into the JavaDoc format.
-// This starts a new javadoc comment block.
-func javaDoc(vdlComment string) string {
-	if vdlComment == "" {
-		return ""
-	}
-	return "/**" + javaDocInComment(vdlComment) + "\n */\n"
+	ret += "*/"
+	return ret
 }