Android Room Persistence library and Kotlin - database

I am trying to write a simple app using Kotlin and Room Persistence Library.
I followed the tutorial in the Android Persistence codelab.
Here is my AppDatabase class in Kotlin:
#Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userModel(): UserDao
companion object {
private var INSTANCE: AppDatabase? = null
#JvmStatic fun getInMemoryDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
INSTANCE = Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).allowMainThreadQueries().build()
}
return INSTANCE!!
}
#JvmStatic fun destroyInstance() {
INSTANCE = null
}
}
}
But when I tried to run the app, it crashes immediately.
Here is the crash log:
Caused by: java.lang.RuntimeException: cannot find implementation for com.ttp.kotlin.kotlinsample.room.AppDatabase. AppDatabase_Impl does not exist
at android.arch.persistence.room.Room.getGeneratedImplementation(Room.java:90)
at android.arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.java:340)
at com.ttp.kotlin.kotlinsample.room.AppDatabase$Companion.getInMemoryDatabase(AppDatabase.kt:19)
at com.ttp.kotlin.kotlinsample.MainKotlinActivity.onCreate(MainKotlinActivity.kt:28)
at android.app.Activity.performCreate(Activity.java:6272)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494) 
at android.app.ActivityThread.access$900(ActivityThread.java:157) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
It looks like the class AppDatabase_Impl wasn't autogenerated. I checked the original java app downloaded from codelab and found that AppDatabase_Impl was autogenerated.
Kotlin version: 1.1.2-3
Room version: 1.0.0-alpha1
Is there anyone experienced with this?
Edit:
Using kapt solves my problem. In my case, I have to replace annotationProcessor with kapt.

Usually in project build.gradle I define the dependencies versions:
ext {
buildToolsVersion = '25.0.2'
supportLibVersion = '25.3.1'
espressoVersion = '2.2.2'
archRoomVersion = '1.0.0-alpha1'
}
so in app build.gradle the dependencies look like:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile "com.android.support:appcompat-v7:${rootProject.supportLibVersion}"
compile "android.arch.persistence.room:runtime:${rootProject.archRoomVersion}"
annotationProcessor "android.arch.persistence.room:compiler:${rootProject.archRoomVersion}"
kapt "android.arch.persistence.room:compiler:${rootProject.archRoomVersion}"
androidTestCompile("com.android.support.test.espresso:espresso-core:${rootProject.espressoVersion}", {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
}
Now you can define Entities Daos and Database in Kotlin.
Database:
#Database(entities = arrayOf(User::class), version = 1)
abstract class Database : RoomDatabase() {
abstract fun userDao(): UserDao
}
Entity:
#Entity(tableName = "user")
class User {
#PrimaryKey(autoGenerate = true)
var id: Int = 0
var name: String = ""
}
Dao:
#Dao
interface UserDao {
#Query("SELECT * FROM user")
fun getAll(): List<User>
#Insert
fun insertAll(vararg users: User)
#Delete
fun delete(user: User)
}
NB: Query with parameters.
Kotlin renames params, so the SQL query to retrieve all the emails that belong at a user via the userId is:
#Query("SELECT * FROM email "
+ "INNER JOIN user ON user.id = email.userId "
+ "WHERE user.id = :arg0")
fun getEmailsForUser(userId: Int): List<Email>

In my case, in build.gradle, when you have "annotationProcessor" you need to duplicate with "kapt" and it works.
compile "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"

Try out these steps
Step 1. Set the room_version in the project.gradle file
buildscript {
ext.kotlin_version = '1.1.51'
ext.room_version = '1.0.0-alpha9-1'
...
Step 2. Apply the kotlin-kapt plugin in the app.gradle file, and this solved my issue.
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
...
Step 3. Add the kapt dependency in the app.gradle file
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
...
}

Anyone interested in using Kotlin with Room and Data Binding can see this sample project https://github.com/entrpn/kotlin-room-databinding

i almost gave up. but after doing just what dharmin007 said i also had to clean the project. that made it work. I've noticed that whenever you add kapt to gradle you MUST clean the project after synching gradle.

I don't know if there is a necessity to my answer I know that some of the above answers already included this to their answers but they added other things
ONLY ADD
apply plugin: 'kotlin-kapt'

Related

In allure report unable to see logger statements put inside #Step annotated method

I am doing POC on allure reporting.I created a Gradle project that has a test class with two #Test annotated methods.The same test class has #Step annotated method that has logger statements.This #Step annotated method is called from one of the #Test annotated methods.Upon running the tests,I do not see the logger info(present under #Step method) in allure result.
I have added needed dependencies and plugin in build.gradle.
content of build.gradle file.
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* user guide available at https://docs.gradle.org/4.8.1/userguide/java_library_plugin.html
*/
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id "io.qameta.allure" version "2.8.1"
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'io.qameta.allure:allure-testng:2.12.0'
implementation 'org.testng:testng:6.9.9'
compile('org.aspectj:aspectjweaver:1.9.4')
compile 'org.slf4j:slf4j-api:1.7.25'
compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.0.2'
compile 'org.apache.logging.log4j:log4j-web:2.0.2'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:23.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
allure {
version = '2.8.1'
autoconfigure = true
aspectjweaver = true
useTestNG {
version = '2.0-BETA20'
}
}
my sample test code:
public class SampleTestForAllureReport {
public static Logger logger = LoggerFactory.getLogger(SampleTestForAllureReport.class);
#Severity(SeverityLevel.BLOCKER)
#Description("This is a sample test for printing welcome")
#Test()
public void welcomeEvent()
{
loggingSteps();
System.out.println("WELCOME");
}
#Test()
public void exitEvent()
{
System.out.println("EXIT");
}
#Step("logger for welcome test")
public void loggingSteps()
{
logger.info("log for step1");
}
}
allure result.

kotlin.KotlinNullPointerException while accessing Data from local Room Database?

I am new into Kotlin and trying to learn, how to fetch Data with retrofit and store this data into a Room DB. But as soon as i start the Activity where this process takes place i get a NullPointerException.
EDIT: As far as i could find out now, my "database" in the RoomViewmodel class is still NULL when i want to access it, even though i have an override oncreate function, where it is created
Here is also a link to the GitHub repository from the mini-project I'm working on: https://github.com/Engin92/Dog_Breeds/tree/RoomDatabase
here is my complete errorlist:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dogbreeds, PID: 14803
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dogbreeds/com.example.Breedlist.activity.DetailedViewActivity}: kotlin.KotlinNullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3961)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
Caused by: kotlin.KotlinNullPointerException
at com.example.Breedlist.activity.DetailedViewActivityRepository.getBreeds(DetailedViewActivityRepository.kt:23)
at com.example.Breedlist.activity.DetailedViewActivityViewModel.getAllBreedList(DetailedViewActivityViewModel.kt:23)
at com.example.Breedlist.activity.DetailedViewActivity.onCreate(DetailedViewActivity.kt:42)
at android.app.Activity.performCreate(Activity.java:8086)
at android.app.Activity.performCreate(Activity.java:8074)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1313)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3755)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3961) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386) 
at android.os.Handler.dispatchMessage(Handler.java:107) 
at android.os.Looper.loop(Looper.java:213) 
at android.app.ActivityThread.main(ActivityThread.java:8178) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101) 
The important part of DetailedViewActivity
class DetailedViewActivity : AppCompatActivity() {
lateinit var breedRecyclerView: RecyclerView
lateinit var detailedViewActivityViewModel: DetailedViewActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detailed_view)
breedRecyclerView = findViewById(R.id.breedRecyclerView)
detailedViewActivityViewModel = ViewModelProviders.of(this).get(
DetailedViewActivityViewModel::class.java)
if(isOnline(this))
{
detailedViewActivityViewModel.getBreedsFromAPIAndStore()
}
else
{
Toast.makeText(this,"No internet connection. Showing cached list!",Toast.LENGTH_LONG).show()
}
detailedViewActivityViewModel.getAllBreedList().observe(this, Observer<List<CurrentBreedResponseItem>> { breedList ->
Log.e(MainActivity::class.java.simpleName,breedList.toString())
setUpBreedRecyclerView(breedList!!)
})
} ....
the class RoomViewModel, where i build the DB (where i Think the error is, the var database is still NULL, after trying to access (write/read) it)
class RoomViewModel : Application() {
companion object {
var database: BreedDatabase? = null
}
override fun onCreate() {
super.onCreate()
database = Room.databaseBuilder(applicationContext, BreedDatabase::class.java, "breed_db").fallbackToDestructiveMigration().build()
}
}
getBreeds function in DetailedViewActivityRepository:
fun getBreeds() : LiveData<List<CurrentBreedResponseItem>>
{
return RoomViewModel.database!!.currentBreedDao().getAllBreeds()
}
getAllBreedList function in DetailedViewActivityViewModel
fun getAllBreedList(): LiveData<List<CurrentBreedResponseItem>>
{
return detailedViewActivityRepository.getBreeds()
}
There are two problem in your code. The first one is very clear you are trying to access a null object and you are getting NullPointerException. So be careful when you use !! operator.
The reason you are getting it is, inside your RoomViewModel your database instance is null.
class RoomViewModel : Application() {
companion object {
var database: BreedDatabase? = null
}
override fun onCreate() {
super.onCreate()
database = Room.databaseBuilder(applicationContext, BreedDatabase::class.java, "breed_db")
.fallbackToDestructiveMigration().build()
}
}
You may think you are initializing the database instance in onCreate() but the onCreate() is not getting called. The reason is to make the application class work you need to add it to your AndroidManifest.xml file.
Solution:
Add this RoomViewModel class to your AndroidManifest.xml file like this.
<application
android:name=".view.RoomViewModel"
android:allowBackup="true"
We do it as application tag's name attribute as you can see above.
This will fix your null pointer exception. But your program will again crash, because you are using Kotlin and do make room work with kotlin this thing needs to be added in your app level build.gradle file.
kapt "android.arch.persistence.room:compiler:1.1.1"
After adding it to your app level build.gradle inside dependencies block. Sync your project and run it should work.
If you want to learn more about Room Database in Android, you can check this Room Database Tutorial.
Hope this will help you.

How to add Kotlin support for Google Java Cloud Endpoints

I'm trying to use Kotlin for Google Java Cloud Endpoints, but I'm getting the following Exception deserializing Kotlin data classes
INFO: exception occurred while calling backend method
com.google.api.server.spi.response.BadRequestException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of my.package.Foo: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: UNKNOWN; line: -1, column: -1]
at com.google.api.server.spi.request.RestServletRequestParamReader.read(RestServletRequestParamReader.java:128)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:349)
at com.google.api.server.spi.handlers.EndpointsMethodHandler$RestHandler.handle(EndpointsMethodHandler.java:119)
at com.google.api.server.spi.handlers.EndpointsMethodHandler$RestHandler.handle(EndpointsMethodHandler.java:102)
at com.google.api.server.spi.dispatcher.PathDispatcher.dispatch(PathDispatcher.java:50)
at com.google.api.server.spi.EndpointsServlet.service(EndpointsServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
...
My Kotlin files...
// file: Foo.kt
data class Foo(val bar: String) {
}
// file: MyEndpoint.kt
// My GET works fine as Serialization Does work
#ApiMethod(name = "getFoo",
description = "testing get",
path = "getFoo",
httpMethod = ApiMethod.HttpMethod.GET)
fun getFoo(): Foo {
val myFoo = Foo("myBar")
return myFoo
}
// My Post doesn't work, de-serialization is broken
#ApiMethod(name = "postFoo",
description = "testing post",
path = "postFoo",
httpMethod = ApiMethod.HttpMethod.POST)
fun postFoo(myFoo: Foo): Foo {
val postFoo = Foo(myFoo.bar)
return postFoo
}
I can see that I need to add the KotlinModule to the Jackson ObjectMapper
// file: build.gradle
compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.8.4")
// adding this will fix the problem, but Where??
objectMapper.registerModule(new KotlinModule());
Where do I manupulate the 'Global' ObjectMapper for Java Endpoints?
I can see that I could add a Transformer to either the #Api or the data classes themselves.
If I add it to the #Api, I don't appear to get any type information, so that's out
Adding it to the data classes involves me making another Transformer for Every data class. Which
seems it would work, but adds A LOT of cruft.
Is there an elegant solution for setting/modifying the default ObjectMapper?

Bootstrapping NancyFX with RavenDB

I am trying to add bootstrap NancyFX with RavenDB and I am running into the following error trying to run the application...
"Unable to resolve type: Nancy.IResponseFormatter"
Environment:
ASP.Net
Nancy
Nancy.Hosting.Aspnet
RavenDB
VS2010 DevelopmentServer
In lieu of pasting all of the code, here is a link to the site that I used as an example. By example, I mean I copied it verbatim to see if I could get it to work.
http://stuff-for-geeks.com/category/NancyFx.aspx
I have actually seen this code run in a demo before, but I for some reason can not get it to run at all. It fails at start up. It is almost as if Nancy is not using my BootStrapper.
More of the Stack Trace:
[TypeInitializationException: The type initializer for 'Nancy.Hosting.Aspnet.NancyHttpRequestHandler' threw an exception.]
Nancy.Hosting.Aspnet.NancyHttpRequestHandler..ctor() +0
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
Any help would be really appreciated.
That code is based on an older version of Nancy. You should be looking at using the IResponseFormatterFactory instead. The custom module builder, that is defined in the blog post, is based on an old copy of the DefaultNancyModuleBuilder and if you have a look at the current version https://github.com/NancyFx/Nancy/blob/master/src/Nancy/Routing/DefaultNancyModuleBuilder.cs you should be able to make the necessary adjustments
Here is the code for the RavenAwareModuleBuilder class under discussion:
Edit 1
The code below has been updated for Nancy Release 0.12. Note the new NegotiationContext lines in BuildModule method.
public class RavenAwareModuleBuilder : INancyModuleBuilder
{
private readonly IViewFactory viewFactory;
private readonly IResponseFormatterFactory responseFormatterFactory;
private readonly IModelBinderLocator modelBinderLocator;
private readonly IModelValidatorLocator validatorLocator;
private readonly IRavenSessionProvider ravenSessionProvider;
public RavenAwareModuleBuilder(IViewFactory viewFactory, IResponseFormatterFactory responseFormatterFactory, IModelBinderLocator modelBinderLocator, IModelValidatorLocator validatorLocator, IRavenSessionProvider ravenSessionProvider)
{
this.viewFactory = viewFactory;
this.responseFormatterFactory = responseFormatterFactory;
this.modelBinderLocator = modelBinderLocator;
this.validatorLocator = validatorLocator;
this.ravenSessionProvider = ravenSessionProvider;
}
public NancyModule BuildModule(NancyModule module, NancyContext context)
{
context.NegotiationContext = new NegotiationContext
{
ModuleName = module.GetModuleName(),
ModulePath = module.ModulePath,
};
module.Context = context;
module.Response = this.responseFormatterFactory.Create(context);
module.ViewFactory = this.viewFactory;
module.ModelBinderLocator = this.modelBinderLocator;
module.ValidatorLocator = this.validatorLocator;
context.Items.Add(
"IDocumentSession",
ravenSessionProvider.GetSession()
);
module.After.AddItemToStartOfPipeline(ctx =>
{
var session = ctx.Items["IDocumentSession"] as IDocumentSession;
if (session != null) session.Dispose();
});
return module;
}
}

Example of testing a RPC call using GWT-TestCase with GAE

How is that for a lot of acronyms!
I am having trouble testing GWT's RPC mechanism using GWT's GWTTestCase. I created a class for testing using the junitCreator tool included with GWT. I am attempting to test using the built in Google App Engine using the created "hosted mode" testing profile created by junitCreator. When I run the test, I keep getting errors saying things like
Starting HTTP on port 0
HTTP listening on port 49569
The development shell servlet received a request for 'greet' in module 'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml'
[WARN] Resource not found: greet; (could a file be missing from the public path or a <servlet> tag misconfigured in module com.google.gwt.sample.stockwatcher.StockWatcher.JUnit.gwt.xml ?)
com.google.gwt.user.client.rpc.StatusCodeException: Cannot find resource 'greet' in the public path of module 'com.google.gwt.sample.stockwatcher.StockWatcher.JUnit'
I hope that someone somewhere has successfully run junit test (using GWTTestCase or just plain TestCase) that will allow for the testing of gwt RPC. If this is the case, could you please mention the steps you took, or better yet, just post code that works. Thanks.
SyncProxy allows you to make GWT RPC call from Java. So you can test your GWT RPC with regular Testcase (and faster than GwtTestcase)
See
http://www.gdevelop.com/w/blog/2010/01/10/testing-gwt-rpc-services/
http://www.gdevelop.com/w/blog/2010/03/13/invoke-gwt-rpc-services-deployed-on-google-app-engine/
I got this working. This answer assume's you're using Gradle, but this could easily be adopted to run from ant. First, you'll have to make sure that you separate your GWT tests from your regular JUnit tests. I created 'tests/standalone' for the regular tests, and 'tests/gwt' for my GWT tests. I still get 1 single HTML report in the end that has all of the info.
Next, you need to make sure JUnit is part of your ant classpath, as described here:
http://gradle.1045684.n5.nabble.com/Calling-ant-test-target-fails-with-junit-classpath-issue-newbie-td4385167.html
Then, use something similar to this to compile your GWT tests and run them:
task gwtTestCompile(dependsOn: [compileJava]) << {
ant.echo("Copy the test sources in so they're part of the source...");
copy {
from "tests/gwt"
into "$buildDir/src"
}
gwtTestBuildDir = "$buildDir/classes/test-gwt";
(new File(gwtTestBuildDir)).mkdirs()
(new File("$buildDir/test-results")).mkdirs()
ant.echo("Compile the tests...");
ant.javac(srcdir: "tests/gwt", destdir: gwtTestBuildDir) {
classpath {
pathElement(location: "$buildDir/src")
pathElement(location: "$buildDir/classes/main")
pathElement(path: configurations.runtime.asPath)
pathElement(path: configurations.testCompile.asPath)
pathElement(path: configurations.gwt.asPath)
pathElement(path: configurations.gwtSources.asPath)
}
}
ant.echo("Run the tests...");
ant.junit(haltonfailure: "true", fork: "true") {
classpath {
pathElement(location: "$buildDir/src")
pathElement(location: "$buildDir/classes/main")
pathElement(location: gwtTestBuildDir)
pathElement(path: configurations.runtime.asPath)
pathElement(path: configurations.testCompile.asPath)
pathElement(path: configurations.gwt.asPath)
pathElement(path: configurations.gwtSources.asPath)
}
jvmarg(value: "-Xmx512m")
jvmarg(line: "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005")
test(name: "com.onlyinsight.client.LoginTest", todir: "$buildDir/test-results")
formatter(type: "xml")
}
}
test.dependsOn(gwtTestCompile);
Finally, here's a simple GWT test:
public class LoginTest extends GWTTestCase
{
public String getModuleName()
{
return "com.onlyinsight.ConfModule";
}
public void testRealUserLogin()
{
UserServiceAsync userService = UserService.App.getInstance();
userService.login("a", "a", new AsyncCallback<User>()
{
public void onFailure(Throwable caught)
{
throw new RuntimeException("Unexpected Exception occurred.", caught);
}
public void onSuccess(User user)
{
assertEquals("a", user.getUserName());
assertEquals("a", user.getPassword());
assertEquals(UserRole.Administrator, user.getRole());
assertEquals("Test", user.getFirstName());
assertEquals("User", user.getLastName());
assertEquals("canada#onlyinsight.com", user.getEmail());
// Okay, now this test case can finish.
finishTest();
}
});
// Tell JUnit not to quit the test, so it allows the asynchronous method above to run.
delayTestFinish(10 * 1000);
}
}
If your RPC instance doesn't have a handy getInstance() method, then add one:
public interface UserService extends RemoteService {
public User login(String username, String password) throws NotLoggedInException;
public String getLoginURL(OAuthProviderEnum provider) throws NotLoggedInException;
public User loginWithOAuth(OAuthProviderEnum provider, String email, String authToken) throws NotLoggedInException;
/**
* Utility/Convenience class.
* Use UserService.App.getInstance() to access static instance of UserServiceAsync
*/
public static class App {
private static final UserServiceAsync ourInstance = (UserServiceAsync) GWT.create(UserService.class);
public static UserServiceAsync getInstance()
{
return ourInstance;
}
}
}
I hope that helps.

Resources