GithubHelp home page GithubHelp logo

francisdb / serviceloader-maven-plugin Goto Github PK

View Code? Open in Web Editor NEW
48.0 7.0 15.0 206 KB

Maven plugin for generating java serviceloader files

License: Apache License 2.0

Java 100.00%
maven-plugin java serviceloader

serviceloader-maven-plugin's Introduction

Build status Maven Central

This maven plugin generates services files for the ServiceLoader introduced in Java 6 : https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html

Use

for example:

<build>
  <plugins>
    <plugin>
      <groupId>eu.somatik.serviceloader-maven-plugin</groupId>
      <artifactId>serviceloader-maven-plugin</artifactId>
      <version>1.3.1</version>
      <configuration>
        <services>
          <param>com.foo.Dictionary</param>
          <param>com.foo.Operation</param>
        </services>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>generate</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

this will generate these files:

  • META-INF/services/com.foo.Dictionary
  • META-INF/services/com.foo.Operation

by scanning the generated classes and finding all non-abstract/non-interface implementations of the service interfaces. The plugin itself has no Java 6 dependency

Excludes / includes

Additionally it is possible to filter implementation classes via includes and excludes section in the configuration. The class name notation is the same as for the services section.

for example:

<build>
  <plugins>
    <plugin>
      <groupId>eu.somatik.serviceloader-maven-plugin</groupId>
      <artifactId>serviceloader-maven-plugin</artifactId>
      <version>1.3.1</version>
      <configuration>
        <services>
          <param>com.foo.Dictionary</param>
          <param>com.foo.Operation</param>
        </services>
        <includes>
          <include>*.RightClass*</include>
        </includes>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>generate</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

This should add only implementation classes that begin with RightClass*.

Missing Service Classes

The default action when a service class is missing is to fail the build. If you want to ignore this service, you can use the failOnMissingServiceClass option (true by default).

for example:

<build>
  <plugins>
    <plugin>
      <groupId>eu.somatik.serviceloader-maven-plugin</groupId>
      <artifactId>serviceloader-maven-plugin</artifactId>
      <version>1.3.1</version>
      <configuration>
      	<failOnMissingServiceClass>false</failOnMissingServiceClass>
        <services>
          <param>com.foo.MissingService</param>
        </services>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>generate</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Example

A example project is provided and can be run like this:

$ mvn clean install
...
[INFO] Generating service file .../example/target/classes/META-INF/services/eu.somatik.serviceloader.Operation
[INFO]   + eu.somatik.serviceloader.SimpleOperation
...

$ java -jar target/example-1.0-SNAPSHOT.jar
Found service implementation: eu.somatik.serviceloader.SimpleOperation@579a19fd
Hello world

Release

see http://central.sonatype.org/pages/apache-maven.html#performing-a-release-deployment-with-the-maven-release-plugin

Note: do export GPG_TTY=$(tty) first if you have gpg: signing failed: Inappropriate ioctl for device errors

mvn -P release release:clean release:prepare
mvn -P release release:perform

serviceloader-maven-plugin's People

Contributors

berryma4 avatar dependabot[bot] avatar francisdb avatar jamescarter avatar jazdw avatar justinsb avatar lbaali avatar sullis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

serviceloader-maven-plugin's Issues

Maven won't pick up the generated META-INF/services file into the jar

Hello,

This is maven 3.0.4 on Ubuntu x86-64 but I don't think it matters -- or maybe the maven version matters?

The plugin works fine, however, the generated META-INF/services file, in target/classes, does not get included in the jar. I am no maven specialist, which makes it quite hard for me to play around without breaking things, and so far I couldn't get it to work.

Is there a solution to this?

Thanks for this plugin!

Possible to ignore module-info.class?

Currently getting a warning on my modular project:

[INFO] --- serviceloader-maven-plugin:1.3.1:generate (default) @ com-pholser-util-properties-propertybinder ---
[INFO] Scanning generated classes for implementations...
[WARNING] 
java.lang.NoClassDefFoundError: module-info is not a class because access_flag ACC_MODULE is set
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1017)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:550)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:458)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:452)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:451)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:589)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:522)
    at eu.somatik.maven.serviceloader.ServiceloaderMojo.findImplementations (ServiceloaderMojo.java:231)
    at eu.somatik.maven.serviceloader.ServiceloaderMojo.execute (ServiceloaderMojo.java:136)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

Remove interface or abstract class logic

It would be nice of you could remove the if(isInterface or isAbstract) logic, or at least create a configuration variable to disable the checking. We utilize a modified ServiceLoader for loading extensions of non-abstract classes (the JAX-RS Application.class).

Java 1.8 compiled classes are not supported?

at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:179)
... 20 more

Caused by: java.lang.UnsupportedClassVersionError: com.company.Clasz$1 : Unsupported major.minor version 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at eu.somatik.maven.serviceloader.ServiceloaderMojo.findImplementations(ServiceloaderMojo.java:215)
at eu.somatik.maven.serviceloader.ServiceloaderMojo.execute(ServiceloaderMojo.java:123)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)

bykka - serviceloader-maven-plugin windows issues

bykka sent you a message.


Subject: serviceloader-maven-plugin issues

Francisdb,

I have found few issues in the serviceloader-maven-plugin.
I do not know how to use this github that is why I decided to describe everything in this message.

Okey. There are to issues: one is related with running this pluggin on windows OS. Another - when a service implementation is a inner class.

To solve first issue i did next changes in the ServiceloaderMojo.java

line 337:
url = new URL( "file:" + path + "/" );
replaced on
url = new File(path).toURI().toURL();

line 333:
url = new URL( "jar:file:" + path + "!/" );
replaced on
url = new URL( "jar:" + new File(path).toURI().toString() + "!/" );

line 265:
classNames.add( file.substring( 0, file.length() - extension.length()).replace( "/", "." ));
replaced on
classNames.add(file.substring( 0, file.length() - extension.length()).replace( File.separator, "." ));

To solve second issue next expression have been removed from line 227 - "!cls.isMemberClass()"

I hope these changes will be useful for you.

Thank you for your plugin.

Caveat on use with m2e (Maven in Eclipse)

This isn't quite a bug report, more of a warning or an applicability statement.

This plugin is great, and I like the fact that it discovers the classes that implement the service interface (c.f. other approaches where you have to add an annotation to each service implementation class). I believe that it works fine in a pure Maven environment.

Where I got into trouble with it (and why I'll probably end up using one of those other approaches instead) was trying to use it with m2e in Eclipse. This combination led to flakey behaviour: often it worked fine, but occasionally I discovered at runtime that Eclipse/m2e had built a new version of the JAR file that hadn't executed the plugin and hence didn't contain the META-INF/services entry. Bah.

I think I understand what caused this. m2e places extra requirements on Maven plugins:

    http://wiki.eclipse.org/M2E_compatible_maven_plugins#BuildContext

Since this plugin doesn't implement those m2e requirements, I ended up configuring m2e's lifecycleMappingMetadata with its action set to <ignore/> (rather than <execute/>), reasoning that it didn't really matter whether Eclipse builds worked, all that really mattered was the Maven builds (which work fine). But this is exactly what led to the flakiness: if the JAR file that I ended up with at runtime (in a web app built by Eclipse/m2e and deployed on Tomcat under Eclipse) had been produced by a Maven build then all was good, but if for whatever reason Eclipse/m2e had more recently executed an Eclipse build then I silently ended up with a JAR file that contained everything except the META-INF/services entry.

[Perhaps I could also use m2e's Maven --> Disable Workspace Resolution command to work around this (because then, I assume, the JAR artifact would always be a valid one from my local m2 repo rather than the close-but-no-cigar JAR file generated by Eclipse/m2e). I haven't tried that approach].

I'm certainly not suggesting that this plugin should be modified to make it play by m2e's rules (that would be quite a bit of work). Feel free to close this issue; I mainly logged it as an FYI for anyone else who might try the combo of this (pretty neat) plugin and m2e.

Interface located in third party jar

Hello I'm trying to create a jar with services but the interface of the services is declared in a common jar.

I tried to add a custom classpath entry for the plugin execution but it tells me that the interface could not be loaded (ClassNotFound)

Below the plugin configuration used :

<plugin>
                <groupId>eu.somatik.serviceloader-maven-plugin</groupId>
                <artifactId>serviceloader-maven-plugin</artifactId>
                <configuration>
                    <services>
                        <param>my.Interface</param>
                    </services>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>groupId</groupId>
                        <artifactId>common-jar</artifactId>
                        <version>version</version>
                    </dependency>
                </dependencies>
            </plugin>

Plugin doesn't work with maven 2

This might be closed as "WONTFIX", but...

I just tested and the class scanning does not work under maven 2 (which is the default version available for Debian 6, mvn3 is not even available on backports). It doesn't find any class so the generated service file is empty.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.