/** * Checks type and its supertypes for {@link ExtraTypes} annotations. * * @param type the type to examine * @param addModelExtraTypes if {@code true} the contents of the {@link #extraTypes} field will be * added to the returned list. */ private List<EntityProxyModel> checkExtraTypes(JClassType type, boolean addModelExtraTypes) throws UnableToCompleteException { Set<EntityProxyModel> toReturn = new LinkedHashSet<EntityProxyModel>(); if (addModelExtraTypes && extraTypes != null) { toReturn.addAll(extraTypes); } for (JClassType toExamine : type.getFlattenedSupertypeHierarchy()) { ExtraTypes proxyExtraTypes = toExamine.getAnnotation(ExtraTypes.class); if (proxyExtraTypes != null) { for (Class<? extends BaseProxy> clazz : proxyExtraTypes.value()) { JClassType proxy = oracle.findType(clazz.getCanonicalName()); if (proxy == null) { poison( "Unknown class %s in @%s", clazz.getCanonicalName(), ExtraTypes.class.getSimpleName()); } else { toReturn.add(getEntityProxyType(proxy)); } } } } if (toReturn.isEmpty()) { return Collections.emptyList(); } return new ArrayList<EntityProxyModel>(toReturn); }
private static Map<JType, JClassType> findCustomSerializers(TypeOracle oracle) throws NotFoundException { Map<JType, JClassType> serializers = new HashMap<JType, JClassType>(); JClassType serializerInterface = oracle.findType(JSONSerializer.class.getName()); JType[] deserializeParamTypes = new JType[] { oracle.findType(com.vaadin.client.metadata.Type.class.getName()), oracle.findType(JSONValue.class.getName()), oracle.findType(ApplicationConnection.class.getName()) }; String deserializeMethodName = "deserialize"; // Just test that the method exists serializerInterface.getMethod(deserializeMethodName, deserializeParamTypes); for (JClassType serializer : serializerInterface.getSubtypes()) { JMethod deserializeMethod = serializer.findMethod(deserializeMethodName, deserializeParamTypes); if (deserializeMethod == null) { continue; } JType returnType = deserializeMethod.getReturnType(); serializers.put(returnType, serializer); } return serializers; }
/** Implement additional methods defined in {@link AbstractUiCommonModelEditorDriver} */ @Override protected void writeAdditionalContent( TreeLogger logger, GeneratorContext context, EditorModel model, SourceWriter sw) throws UnableToCompleteException { TypeOracle typeOracle = context.getTypeOracle(); baseModelType = eraseType( typeOracle.findType("org.ovirt.engine.ui.uicommonweb.models.Model")); // $NON-NLS-1$ entityModelType = eraseType( typeOracle.findType( "org.ovirt.engine.ui.uicommonweb.models.EntityModel")); //$NON-NLS-1$ listModelType = eraseType( typeOracle.findType("org.ovirt.engine.ui.uicommonweb.models.ListModel")); // $NON-NLS-1$ hasCleanupType = eraseType(typeOracle.findType("org.ovirt.engine.ui.uicommonweb.HasCleanup")); // $NON-NLS-1$ this.logger = logger; this.model = model; this.sw = sw; logger.log(Type.DEBUG, "Starting to write additional Driver code"); // $NON-NLS-1$ writeListenerMap(); writeEventMap(); writeOwnerModels(); writeCleanup(); }
@Override public String interpretElement(XMLElement elem) throws UnableToCompleteException { if (!uiWriter.isWidgetElement(elem)) { return super.interpretElement(elem); } JClassType type = uiWriter.findFieldType(elem); TypeOracle oracle = uiWriter.getOracle(); MessagesWriter mw = uiWriter.getMessages(); String name = mw.consumeMessageAttribute("ph", elem); if ("".equals(name)) { name = "widget" + (++serial); } String idHolder = uiWriter.declareDomIdHolder(null); idToWidgetElement.put(idHolder, elem); if (oracle.findType(HasHTML.class.getName()).isAssignableFrom(type)) { return handleHasHTMLPlaceholder(elem, name, idHolder); } if (oracle.findType(HasText.class.getName()).isAssignableFrom(type)) { return handleHasTextPlaceholder(elem, name, idHolder); } return handleOpaqueWidgetPlaceholder(elem, name, idHolder); }
// BEGIN MODIFICATION private FieldManager getFieldManager( TypeOracle oracle, MortalLogger logger, PropertyOracle propertyOracle, boolean useLazyWidgetBuilder) throws UnableToCompleteException { // Find ginjector FieldManager fieldManager; try { String ginjectorClassName = propertyOracle.getConfigurationProperty("gin.ginjector").getValues().get(0); JClassType ginjectorClass = oracle.findType(ginjectorClassName); if (ginjectorClass == null || !ginjectorClass.isAssignableTo(oracle.findType(Ginjector.class.getCanonicalName()))) { logger.die( "The configuration property 'gin.ginjector' is '%s' " + " which doesn't identify a type inheriting from 'Ginjector'.", ginjectorClassName); } fieldManager = new GinFieldManager(oracle, logger, ginjectorClass, useLazyWidgetBuilder); } catch (BadPropertyValueException e) { logger.warn( "The configuration property 'gin.ginjector' was not found, it is required to use " + "gin injection for UiBinder fields. If you don't need this consider using " + "UiBinder.gwt.xml instead of GinUiBinder.gwt.xml in your module."); fieldManager = new FieldManager(oracle, logger, useLazyWidgetBuilder); } return fieldManager; }
public RequestFactoryModel(TreeLogger logger, JClassType factoryType) throws UnableToCompleteException { this.logger = logger; this.factoryType = factoryType; this.oracle = factoryType.getOracle(); collectionInterface = oracle.findType(Collection.class.getCanonicalName()); entityProxyInterface = oracle.findType(EntityProxy.class.getCanonicalName()); instanceRequestInterface = oracle.findType(InstanceRequest.class.getCanonicalName()); listInterface = oracle.findType(List.class.getCanonicalName()); mapInterface = oracle.findType(Map.class.getCanonicalName()); requestContextInterface = oracle.findType(RequestContext.class.getCanonicalName()); requestFactoryInterface = oracle.findType(RequestFactory.class.getCanonicalName()); requestInterface = oracle.findType(Request.class.getCanonicalName()); setInterface = oracle.findType(Set.class.getCanonicalName()); splittableType = oracle.findType(Splittable.class.getCanonicalName()); valueProxyInterface = oracle.findType(ValueProxy.class.getCanonicalName()); extraTypes = checkExtraTypes(factoryType, false); for (JMethod method : factoryType.getOverridableMethods()) { if (method.getEnclosingType().equals(requestFactoryInterface)) { // Ignore methods defined an RequestFactory itself continue; } if (method.getParameters().length > 0) { poison("Unexpected parameter on method %s", method.getName()); continue; } JClassType contextType = method.getReturnType().isInterface(); if (contextType == null || !requestContextInterface.isAssignableFrom(contextType)) { poison( "Unexpected return type %s on method %s is not" + " an interface assignable to %s", method.getReturnType().getQualifiedSourceName(), method.getName(), requestContextInterface.getSimpleSourceName()); continue; } ContextMethod.Builder builder = new ContextMethod.Builder(); builder.setDeclaredMethod(method); buildContextMethod(builder, contextType); contextMethods.add(builder.build()); } if (poisoned) { die(poisonedMessage()); } }
protected void generateCheckRpcTokenTypeOverride( SourceWriter srcWriter, TypeOracle typeOracle, SerializableTypeOracle typesSentFromBrowser) { JClassType rpcTokenType = typeOracle.findType(RpcToken.class.getName()); JClassType[] rpcTokenSubtypes = rpcTokenType.getSubtypes(); String rpcTokenImplementation = ""; for (JClassType rpcTokenSubtype : rpcTokenSubtypes) { if (typesSentFromBrowser.isSerializable(rpcTokenSubtype)) { if (rpcTokenImplementation.length() > 0) { // >1 implematation of RpcToken, bail rpcTokenImplementation = ""; break; } else { rpcTokenImplementation = rpcTokenSubtype.getQualifiedSourceName(); } } } if (rpcTokenImplementation.length() > 0) { srcWriter.println("@Override"); srcWriter.println("protected void checkRpcTokenType(RpcToken token) {"); srcWriter.indent(); srcWriter.println("if (!(token instanceof " + rpcTokenImplementation + ")) {"); srcWriter.indent(); srcWriter.println( "throw new RpcTokenException(\"Invalid RpcToken type: " + "expected '" + rpcTokenImplementation + "' but got '\" + " + "token.getClass() + \"'\");"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.outdent(); srcWriter.println("}"); } }
public void testDashesMatchesCamels() { JClassType stringType = types.findType("java.lang.String"); JClassType cssResourceType = stringType; // TODO(rjrjr) get real someday ImplicitCssResource css = new ImplicitCssResource( "package", "ClassName", "fieldName", new String[] {}, cssResourceType, ".ableBaker {}", MortalLogger.NULL, Collections.<JClassType>emptySet()); FieldWriterOfGeneratedCssResource f = new FieldWriterOfGeneratedCssResource(stringType, css, MortalLogger.NULL); assertEquals( stringType, f.getReturnType( new String[] {"fieldName", "able-baker"}, new MonitoredLogger(MortalLogger.NULL))); assertEquals(FieldWriterType.GENERATED_CSS, f.getFieldType()); }
@Override void toJS(FragmentGeneratorContext context) throws UnableToCompleteException { TreeLogger logger = context.parentLogger.branch( TreeLogger.DEBUG, "Writing function() wrapper for JSFunction", null); SourceWriter sw = context.sw; TypeOracle typeOracle = context.typeOracle; JClassType functionClass = context.returnType.isClassOrInterface(); if (functionClass.equals(typeOracle.findType(JSFunction.class.getName()))) { logger.log( TreeLogger.ERROR, "You must use a subinterface of JSFunction" + " so that the generator can extract a method signature.", null); throw new UnableToCompleteException(); } // This is to support the JSFunction having the same lifetime as the // JSFunction object without having to use GWT.create on every JSFunction // object as that would discourage anonymous classes. sw.print("("); sw.print(context.parameterName); // sw.print("[email protected]::exportedFunction || ("); sw.print(".@" + JSFunction.class.getName() + "::exportedFunction || ("); sw.print(context.parameterName); // sw.print("[email protected]::exportedFunction = "); sw.print(".@" + JSFunction.class.getName() + "::exportedFunction = "); writeFunctionForMethod(context, findExportedMethod(logger, functionClass)); sw.print("))"); }
private Set<BeanResolver> getFileDeclaredTypes(TreeLogger logger, TypeOracle oralce) throws UnableToCompleteException { HashSet<BeanResolver> results = new HashSet<BeanResolver>(); ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader(); try { Enumeration<URL> introspections = ctxLoader.getResources("gwittir-introspection.properties"); while (introspections.hasMoreElements()) { URL propsUrl = introspections.nextElement(); logger.log(TreeLogger.Type.INFO, "Loading: " + propsUrl.toString()); Properties props = new Properties(); props.load(propsUrl.openStream()); for (Entry entry : props.entrySet()) { String className = entry.getKey().toString(); String[] includedProps = entry.getValue().toString().split(","); JClassType type = oralce.findType(className); if (type == null) { logger.log( TreeLogger.Type.ERROR, "Unable to find type " + className + " declared in " + propsUrl); throw new UnableToCompleteException(); } results.add(new BeanResolver(logger, type, includedProps)); } } } catch (IOException ioe) { logger.log(TreeLogger.Type.WARN, "Exception looking for properties files", ioe); } return results; }
private boolean hasDateTimeFormatConstructor(TypeOracle typeOracle, JClassType type) { JType dateTimeFormatType = typeOracle.findType(DateTimeFormat.class.getName()); return TypeOracleUtils.hasCompatibleConstructor(type, dateTimeFormatType); }
/** * Creates the client-side proxy class. * * @throws UnableToCompleteException */ public String create(TreeLogger logger, GeneratorContextExt context) throws UnableToCompleteException { TypeOracle typeOracle = context.getTypeOracle(); JClassType serviceAsync = typeOracle.findType(serviceIntf.getQualifiedSourceName() + "Async"); if (serviceAsync == null) { logger.branch( TreeLogger.ERROR, "Could not find an asynchronous version for the service interface " + serviceIntf.getQualifiedSourceName(), null); RemoteServiceAsyncValidator.logValidAsyncInterfaceDeclaration(logger, serviceIntf); throw new UnableToCompleteException(); } SourceWriter srcWriter = getSourceWriter(logger, context, serviceAsync); if (srcWriter == null) { return getProxyQualifiedName(); } // Make sure that the async and synchronous versions of the RemoteService // agree with one another // RemoteServiceAsyncValidator rsav = new RemoteServiceAsyncValidator(logger, typeOracle); Map<JMethod, JMethod> syncMethToAsyncMethMap = rsav.validate(logger, serviceIntf, serviceAsync); final PropertyOracle propertyOracle = context.getPropertyOracle(); // Load the blacklist/whitelist TypeFilter blacklistTypeFilter = new BlacklistTypeFilter(logger, propertyOracle); // Determine the set of serializable types Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_STOB); SerializableTypeOracleBuilder typesSentFromBrowserBuilder = new SerializableTypeOracleBuilder(logger, propertyOracle, context); typesSentFromBrowserBuilder.setTypeFilter(blacklistTypeFilter); SerializableTypeOracleBuilder typesSentToBrowserBuilder = new SerializableTypeOracleBuilder(logger, propertyOracle, context); typesSentToBrowserBuilder.setTypeFilter(blacklistTypeFilter); addRoots(logger, typeOracle, typesSentFromBrowserBuilder, typesSentToBrowserBuilder); try { ConfigurationProperty prop = context .getPropertyOracle() .getConfigurationProperty(TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC); elideTypeNames = Boolean.parseBoolean(prop.getValues().get(0)); } catch (BadPropertyValueException e) { logger.log( TreeLogger.ERROR, "Configuration property " + TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC + " is not defined. Is RemoteService.gwt.xml inherited?"); throw new UnableToCompleteException(); } // Decide what types to send in each direction. // Log the decisions to a string that will be written later in this method SerializableTypeOracle typesSentFromBrowser; SerializableTypeOracle typesSentToBrowser; String rpcLog; { StringWriter stringWriter = new StringWriter(); PrintWriter writer = new PrintWriter(stringWriter); typesSentFromBrowserBuilder.setLogOutputWriter(writer); typesSentToBrowserBuilder.setLogOutputWriter(writer); writer.write("====================================\n"); writer.write("Types potentially sent from browser:\n"); writer.write("====================================\n\n"); writer.flush(); typesSentFromBrowser = typesSentFromBrowserBuilder.build(logger); writer.write("===================================\n"); writer.write("Types potentially sent from server:\n"); writer.write("===================================\n\n"); writer.flush(); typesSentToBrowser = typesSentToBrowserBuilder.build(logger); writer.close(); rpcLog = stringWriter.toString(); } event.end(); generateTypeHandlers(logger, context, typesSentFromBrowser, typesSentToBrowser); String serializationPolicyStrongName = writeSerializationPolicyFile(logger, context, typesSentFromBrowser, typesSentToBrowser); String remoteServiceInterfaceName = elideTypeNames ? TypeNameObfuscator.SERVICE_INTERFACE_ID : SerializationUtils.getRpcTypeName(serviceIntf); generateProxyFields( srcWriter, typesSentFromBrowser, serializationPolicyStrongName, remoteServiceInterfaceName); generateProxyContructor(srcWriter); generateProxyMethods(srcWriter, typesSentFromBrowser, typeOracle, syncMethToAsyncMethMap); generateStreamWriterOverride(srcWriter); generateCheckRpcTokenTypeOverride(srcWriter, typeOracle, typesSentFromBrowser); srcWriter.commit(logger); if (context.isProdMode() || logger.isLoggable(TreeLogger.DEBUG)) { // Create an artifact explaining STOB's decisions. It will be emitted by // RpcLogLinker context.commitArtifact( logger, new RpcLogArtifact( serviceIntf.getQualifiedSourceName(), serializationPolicyStrongName, rpcLog)); } return getProxyQualifiedName(); }
@Override public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { // make sure it is an interface TypeOracle oracle = context.getTypeOracle(); propertyAccessInterface = oracle.findType(Name.getSourceNameForClass(PropertyAccess.class)); modelKeyProviderInterface = oracle.findType(Name.getSourceNameForClass(ModelKeyProvider.class)); valueProviderInterface = oracle.findType(Name.getSourceNameForClass(ValueProvider.class)); labelProviderInterface = oracle.findType(Name.getSourceNameForClass(LabelProvider.class)); JClassType toGenerate = oracle.findType(typeName).isInterface(); if (toGenerate == null) { logger.log(TreeLogger.ERROR, typeName + " is not an interface type"); throw new UnableToCompleteException(); } if (!toGenerate.isAssignableTo(propertyAccessInterface)) { logger.log(Type.ERROR, "This isn't a PropertyAccess subtype..."); throw new UnableToCompleteException(); } // Get the name of the new type String packageName = toGenerate.getPackage().getName(); String simpleSourceName = toGenerate.getName().replace('.', '_') + "Impl"; PrintWriter pw = context.tryCreate(logger, packageName, simpleSourceName); if (pw == null) { return packageName + "." + simpleSourceName; } // start making the class, with basic imports ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(packageName, simpleSourceName); factory.addImplementedInterface(typeName); SourceWriter sw = factory.createSourceWriter(context, pw); // for each method, for (JMethod m : toGenerate.getOverridableMethods()) { TreeLogger l = logger.branch(Type.DEBUG, "Building method: " + m.getReadableDeclaration()); // no support for params at this time if (m.getParameters().length != 0) { l.log(Type.ERROR, "Method " + m.toString() + " must not have parameters."); throw new UnableToCompleteException(); } // ask for the types that provide the property data JClassType ret = m.getReturnType().isClassOrInterface(); final AbstractCreator c; if (ret.isAssignableTo(valueProviderInterface)) { c = new ValueProviderCreator(context, l, m); } else if (ret.isAssignableTo(modelKeyProviderInterface)) { c = new ModelKeyProviderCreator(context, l, m); } else if (ret.isAssignableTo(labelProviderInterface)) { c = new LabelProviderCreator(context, l, m); } else { logger.log(Type.ERROR, "Method uses a return type that cannot be generated"); throw new UnableToCompleteException(); } c.create(); // build the method // public ValueProvider<T, V> name() { return NameValueProvider.instance; // } sw.println("public %1$s %2$s() {", m.getReturnType().getQualifiedSourceName(), m.getName()); sw.indentln("return %1$s;", c.getInstanceExpression()); sw.println("}"); } sw.commit(logger); return factory.getCreatedClassName(); }
@Override public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { TypeOracle oracle = context.getTypeOracle(); // JClassType requestQueue = oracle.findType(RequestQueue.class.getName()); JClassType toGenerate = oracle.findType(typeName); if (toGenerate == null) { logger.log(TreeLogger.ERROR, typeName + " is not an interface type"); throw new UnableToCompleteException(); } String packageName = toGenerate.getPackage().getName(); String simpleSourceName = toGenerate.getName().replace('.', '_') + "_Impl"; PrintWriter pw = context.tryCreate(logger, packageName, simpleSourceName); if (pw == null) { return packageName + "." + simpleSourceName; } ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(packageName, simpleSourceName); factory.setSuperclass(AbstractRequestQueueImpl.class.getName()); factory.addImplementedInterface(typeName); SourceWriter sw = factory.createSourceWriter(context, pw); // Collect async services we need to provide access to, and the rpc calls they'll make RequestQueueModel model = collectModel(logger.branch(Type.DEBUG, "Collecting service info"), context, toGenerate); // Build a pair of RPC interfaces for serialization String realRpcInterfaceName = buildRpcInterfaces(logger.branch(Type.DEBUG, "Writing RPC interfaces"), context, model); // Build the getRealService() method String serviceQueueAsync = ServiceQueueBaseAsync.class.getName(); sw.println("public %1$s getRealService() {", serviceQueueAsync); sw.indentln( "return %3$s.<%1$s>create(%2$s.class);", serviceQueueAsync, realRpcInterfaceName, GWT.class.getName()); sw.println("}"); // Build the methods (and maybe types?) that call addRequest() for (AsyncServiceModel service : model.getServices()) { sw.println( "public %1$s %2$s() {", service.getAsyncServiceInterfaceName(), service.getDeclaredMethodName()); sw.indent(); sw.println("return new %1$s() {", service.getAsyncServiceInterfaceName()); sw.indent(); for (AsyncServiceMethodModel method : service.getMethods()) { sw.println("public void %1$s(", method.getMethodName()); StringBuilder argList = new StringBuilder(); StringBuilder types = new StringBuilder("new String[]{"); for (int i = 0; i < method.getArgTypes().size(); i++) { if (i != 0) { sw.print(", "); argList.append(", "); types.append(", "); } JType arg = method.getArgTypes().get(i); sw.print("%1$s arg%2$d", arg.getParameterizedQualifiedSourceName(), i); argList.append("arg").append(i); types.append("\"").append(escape(SerializationUtils.getRpcTypeName(arg))).append("\""); } types.append("}"); if (method.hasCallback()) { if (method.getArgTypes().size() != 0) { sw.print(", "); } sw.print( "%1$s<%2$s> callback", AsyncCallback.class.getName(), method.getReturnTypeName()); } sw.println(") {"); sw.indent(); sw.println( "addRequest(\"%1$s\", \"%2$s\",\n%3$s,\n", escape(service.getServiceName()), escape(method.getMethodName()), types.toString()); if (method.hasCallback()) { sw.indentln("callback,"); } else { sw.indentln("null,"); } sw.indentln("new Object[]{%1$s});", argList.toString()); sw.outdent(); sw.println("}"); } sw.outdent(); sw.println("};"); sw.outdent(); sw.println("}"); } sw.commit(logger); return factory.getCreatedClassName(); }
private RequestQueueModel collectModel( TreeLogger logger, GeneratorContext context, JClassType toGenerate) throws UnableToCompleteException { RequestQueueModel.Builder rqBuilder = new RequestQueueModel.Builder(); TypeOracle typeOracle = context.getTypeOracle(); JClassType requestQueue = typeOracle.findType(RequestQueue.class.getName()); JClassType asyncCallback = typeOracle.findType(AsyncCallback.class.getName()); JClassType voidType = typeOracle.findType(Void.class.getName()); rqBuilder.setRequestQueueInterfaceName(toGenerate.getParameterizedQualifiedSourceName()); AsyncServiceModel.Builder serviceBuilder = new AsyncServiceModel.Builder(); for (JMethod m : toGenerate.getMethods()) { TreeLogger serviceLogger = logger.branch(Type.DEBUG, "Reading async service " + m.getReadableDeclaration()); // Skip those defined at RequestQueue if (m.getEnclosingType().equals(requestQueue)) { continue; } JClassType returnType = m.getReturnType().isClassOrInterface(); if (returnType == null) { serviceLogger.log(Type.ERROR, "Unexpected method return type " + returnType); throw new UnableToCompleteException(); } serviceBuilder.setAsyncServiceInterfaceName(returnType.getParameterizedQualifiedSourceName()); serviceBuilder.setDeclaredMethodName(m.getName()); Service serviceAnnotation = m.getAnnotation(Service.class); if (serviceAnnotation == null) { serviceLogger.log(Type.ERROR, "Missing @Service annotation"); throw new UnableToCompleteException(); } serviceBuilder.setService(serviceAnnotation.value().getName()); AsyncServiceMethodModel.Builder methodBuilder = new AsyncServiceMethodModel.Builder(); for (JMethod asyncMethod : m.getReturnType().isClassOrInterface().getMethods()) { TreeLogger methodLogger = serviceLogger.branch( Type.DEBUG, "Reading service method " + asyncMethod.getReadableDeclaration()); List<JType> types = new ArrayList<JType>(); methodBuilder.setReturnTypeName(voidType.getParameterizedQualifiedSourceName()); boolean asyncFound = false; for (JType param : asyncMethod.getParameterTypes()) { if (asyncFound) { methodLogger.log( Type.WARN, "Already passed an AsyncCallback param - is that what you meant?"); } if (param.isClassOrInterface() != null && param.isClassOrInterface().isAssignableTo(asyncCallback)) { JClassType boxedReturnType = ModelUtils.findParameterizationOf(asyncCallback, param.isClassOrInterface())[0]; methodBuilder .setHasCallback(true) .setReturnTypeName(boxedReturnType.getParameterizedQualifiedSourceName()); asyncFound = true; continue; // should be last, check for this... } types.add(param); } Set<JClassType> throwables = new HashSet<JClassType>(); Throws t = asyncMethod.getAnnotation(Throws.class); if (t != null) { for (Class<? extends Throwable> throwable : t.value()) { throwables.add(typeOracle.findType(throwable.getName())); } } methodBuilder .setMethodName(asyncMethod.getName()) .setArgTypes(types) .setThrowables(throwables); serviceBuilder.addMethod(methodBuilder.build()); } rqBuilder.addService(serviceBuilder.build()); } return rqBuilder.build(); }