Writing a Maven Plugin Unit Test

Posted By Hoyt Summers Pittman

If you are trying to write a Maven plugin with unit tests and following Apache’s Maven documentation you may end up with a dependencies like this :

 <dependencies>
        <dependency>
            <groupid>org.apache.maven</groupid>
            <artifactid>maven-plugin-api</artifactid>
            <version>3.2.5</version>
        </dependency>

        <!-- dependencies to annotations -->
        <dependency>
            <groupid>org.apache.maven.plugin-tools</groupid>
            <artifactid>maven-plugin-annotations</artifactid>
            <version>3.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>org.apache.maven.plugin-testing</groupid>
            <artifactid>maven-plugin-testing-harness</artifactid>
            <version>3.2.0</version>
            <scope>test</scope>
            <type>jar</type>
        </dependency>

    </dependencies>

Because that is what their docs say. Their docs are lies straight from the pits of hell. Your dependencies section should look like this :

<dependencies>
        <dependency>
            <groupid>org.apache.maven</groupid>
            <artifactid>maven-core</artifactid>
            <version>3.2.5</version>
        </dependency>
        <dependency>
            <groupid>org.apache.maven</groupid>
            <artifactid>maven-artifact</artifactid>
            <version>3.2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>org.apache.maven</groupid>
            <artifactid>maven-compat</artifactid>
            <version>3.2.5</version>
        </dependency>

        <!-- dependencies to annotations -->
        <dependency>
            <groupid>org.apache.maven.plugin-tools</groupid>
            <artifactid>maven-plugin-annotations</artifactid>
            <version>3.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>org.apache.maven.plugin-testing</groupid>
            <artifactid>maven-plugin-testing-harness</artifactid>
            <version>3.3.0</version>
            <scope>test</scope>
            <type>jar</type>
        </dependency>
    </dependencies>

I discovered this after trying to debug the following stack trace

Caused by: java.lang.ClassNotFoundException: org.apache.maven.execution.MavenExecutionResult
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 23 more

and only finding a bug in Maven’s tracker marked closed as a duplicate. Duplicate of what? Who knows. Eventually I had to break down to the tried and true method of copying code from a project that works. A big thanks to simpligility and the APL.

Jan 28th, 2015

Another rant on Android Studio

Posted By Hoyt Summers Pittman

There are two types of software in this world, software people complain about and software nobody uses. I use Android Studio and I will murder before going back to Eclipse, but my preferred build system for Android is still Maven. This is not going to change for a very long time because the Gradle integration tooling (IDEs) and the Android Gradle ecosystem aren’t caught up. There are many better tools and plugins which work wonderfully in the Maven ecosystem and fail utterly in the Gradle Ecosystem.

When the correct plugins exist, it is more pleasurable to work in Maven than Gradle full stop. The tooling and autocompletion around Maven is much much better. As a example, I have auto completion for artifacts in my IDE of choice in Maven which is regularly indexed from Central. In Android Studio I do not have this feature. In my preferred IDE, NetBeans, Maven projects are opened unaltered with no weird side effects such as creating dot directories or IDE files. In Android Studio importing an Android Gradle project is like playing roulette. Do I open the project or do I import it? Will Android Studio find my code this time or do I have to close the IDE, delete the directory, re-clone, and try again (an extreme example but this is in comparison to NetBeans where opening always works).

The ecosystem gulf between Maven and Android Gradle is terrifying. Code formatting, license plugins, automated testing harnesses, code coverage reports, etc all JUST WORK with Maven and Android. Android Gradle forks and is incompatible with the Java plugin. This means that every project which exists in Gradle to perform some hideously boring task (i.e. manage license headers) has to be rewritten to include Android support. This doesn’t seem to be happening.

What can Android Studio do to get better? 1) Fix importing code. Don’t leave me with a useless project with just the Gradle view EVER. 2) Don’t drop .iml and .idea directories in my project EVER. 3) Fix auto completion when editing the gradle files. It is REALLY painful right now and trivial tasks (is this still the latest version of this library, is this groupId org.apache.project or org.apache, etc) requires a trip to web browser land instead of an Ctrl+Space to see what is in the drop downs. 4) Make the Android plugin depend on the Java plugin and work correctly with it.

In conclusion, I don’t hate Gradle, I don’t even hate the Android Gradle plugin. I hate the NIH which pervades the Android Gradle plugin and the break from the larger Java ecosystem that it represents.

Jan 26th, 2015

AeroGear Android 2.0 Release

Posted By Hoyt Summers Pittman

AeroGear Android 2.0

It has been a long road since June but here it is, 2.0. If you checked out our alpha back in October things are looking better. We’ve fixed a few bugs, updated a few docs, made a bunch of demos, and are ready to share with the world!

New Features since 1.4

Modularization

Android has a 16-bit method limit in its dex file format. In service to this we have broken the library up into smaller modules. Now you only need pipes you won’t also include the data store. Encryption won’t require OAuth2, etc. Each module is now it its on github repository :

Module Repository Depends on
core https://github.com/aerogear/aerogear-android-core
pipe https://github.com/aerogear/aerogear-android-pipe core
auth https://github.com/aerogear/aerogear-android-auth pipe
security https://github.com/aerogear/aerogear-android-security core
push https://github.com/aerogear/aerogear-android-push pipe
store https://github.com/aerogear/aerogear-android-store security
authz https://github.com/aerogear/aerogear-android-authz pipe, store

AAR packaging

Since 1.4 AAR has become the official, supported library package format for Android. As such apklib has been deprecated and removed. AAR’s of 1.3 and 1.4 were released prior as a preview technology and are now stable and default.

Fluent configuration

Out are the old FooConfig beans and in are fluent builders!

Pipeline pipeline = new Pipeline(SOME_URL);
PipeConfig config = new PipeConfig("myPipeName", MyModel.class);
config.setFoo(foo);
config.setBar(bar);
Pipe pipe = pipeline.pipe(config);
/* snip */
Pipe pipeInAnotherPlace = pipeline.get("name");

Now things look like this:

PipeManager.config("gp-upload", RestfulPipeConfiguration.class)
           .module(AuthorizationManager.getModule(MODULE_NAME))
           .withUrl(new URL("https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart"))
           .requestBuilder(new GoogleDriveFileUploadRequestBuilder())
           .forClass(PhotoHolder.class);
/*snip*/
Pipe pipe = PipeManager.get("gp-upload");

Pluggable Configuration Providers

It is much easier to enhance the manager classes and add new configurations. Before you had to not only write a factory method but also call super classes and such nonsense to make sure you didn’t accidentally break the default classes. Now you just include a static block in your configuration class and everything is gravy!

static {
  AuthenticationManager.registerConfigurationProvider(CustomConfiguration.class, new       ConfigurationProvider<customconfiguration>() {
    @Override
    public CustomConfiguration newConfiguration() {
      return new CustomConfiguration();
    }
  });
}

Migration of integration tests

All of our integration tests for modules are included in the modules project. Before these were a separate project (and a pain to maintain).

Android Maven Plugin 4.0

Among other things this includes a new project source layout, lots of AAR compatibility fixes, deprecation of APKLIB, and many other minor fixes and cleanups. For us it means better support for use in Android Studio projects.

API changes and cleanups

All methods marked @Deprecated in 1.4 have been removed. A few other methods which SHOULD have been deprecated have also been removed. Additionally, all former factory methods deprecated by the new builder pattern have been removed.

Dropping support for old Android versions

We’re dropping support for Gingerbread, Honeycomb, and Ice Cream Sandwich. AeroGear Android is now only supporting Android 4.1+.

Android Lollipop

We support Android Lollipop. All of our builds and tests run against the Lollipop APIs and VM.

Loads of minor bug fixes

Dependency cleanup

We no longer use Guava internally. This will VASTLY reduce the number of methods in use. Since we no longer support Gingerbread, the support-v4 dependency has also been removed.

Facebook OAuth2 Support

The OAuth2 module works with Facebook.

OAuth2 configurable refresh token URL

The URL you use to fetch refresh tokens has been made configurable. Before it was the same as the access token endpoint.

EncryptedSQLStore has explicit open and close methods

EncryptedSQLStore now has methods for opening and closing a la SQLStore.

Seriously, look at our JIRA

Miscellaneous extras

Travis-CI builds

All modules are build and tested in Travis-CI with each commit. This is still ongoing as android support in Travis is quite new.

Cookbook Demos

We’ve ported all of our demos to Android studio and added demos for Social media uploads, KeyCloak, and Android Wear.

You can checkout the code in GitHub

AGReddit

Ever wanted a Reddit browser meant to show of AeroGear’s support for paged data sources and authentication? Well here is your chance!

Chuck Norris Jokes with Wear support

Chuck Norris doesn’t need his wrists to tell you jokes. He has yours. And you will thank him.

Shoot and Share

Take a picture and put it on our favorite social media sites or your own private server secured by KeyCloak.

Feature demos

Auth, Store, and OAuth demos are still there as well.

What is next?

Sync

We’ve started working on a sync library to work with the aerogear-sync-server. This is scheduled to be the big new feature of 2.1. You can track our progress in our JIRA.

And as a sneak peek

More OAuth2

For 2.2 we are going to enhance our authorization suppport. We will include more OAuth2 providers, better KeyCloak support, better Android account integration, and support for custom authentication and authorization through intents in addition to our current WebView approach. Again, you can follow our Jira.

Involvement

Conclusion

Version 2.0 represents a huge cleanup and leap forward for the project. We hope that you will take some time to look at it and provide feedback. As always you can reach us via:

Jan 18th, 2015

AeroGear diffsync preview

Posted By Hoyt Summers Pittman


Nov 24th, 2014
Next Page »