IDEA is giving my groovy class the warning `class "MyClassTest" already exists in "my.class.package". It also doesn't seem to be doing a very good job of keeping the class updated when I run the test. I'll add an assertion guaranteed to fail, or succeed and it won't recognize it until later (later so far seems arbitrary). Given that I have maven tests passing and running correctly I suspect this is simply an IDEA configuration problem
here's my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xenoterracide</groupId>
<artifactId>rpf</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.9.RELEASE</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>testGenerateStubs</goal>
<goal>testCompile</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
<configuration>
<testSources>
<testSource>
<directory>${project.basedir}/src/test/groovy</directory>
<includes>
<include>**/*.groovy</include>
</includes>
</testSource>
</testSources>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.0.DATAJPA-622-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.3.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<!-- use UTF-8 for everything -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<start-class>com.xenoterracide.rpf.Application</start-class>
<java.version>1.8</java.version>
</properties>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<url>http://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>http://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
I've fixed the issue by marking the target folder of the artifact as "Excluded".
I think the duplication is caused by the stub files generated in target/generated-sources/groovy-stubs. IDEA must be too curious about these files and might add them to the source set.
I had the exact same problem and setting target dir as excluded didn't help either. I noticed that the directory:
/target/generated-sources/groovy-stubs/test
was getting set as a Sources Root in IDEA. I'd uncheck that in the UI and the error would go away, but as soon as I'd rebuild project it was back to it again. Very frustrating. Until I started looking at all the gmavenplus-plugin execution goals.
It turned out I had a few too many goals listed. If you're only using groovy for testing purposes, like I am (with Spock - I'm so done with JUnit), you should only have the following goals enabled under that plugin:
addTestSources
testGenerateStubs
testCompile
removeTestStubs
Remove the rest of them. Once you do that IDEA should be all good with your groovy tests (or Specs in my case). Let me know if that really helped.
This is because of IntelliJ knows groovy by nature, the only thing you have to do is DO NOT activate gmaveplus-plugin in IntelliJ:
<profiles>
<profile>
<id>groovy-integration</id>
<!-- profile to incorporate gmaveplus in normal build -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>testGenerateStubs</goal>
<goal>testCompile</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>development-in-idea</id>
<!-- suppress `groovy-integration` profile by default in IntelliJ -->
<activation>
<property>
<name>idea.version</name>
</property>
</activation>
</profile>
</profiles>
One down side is that when you run maven goal from IntelliJ IDEA's Maven Projects tool window directly, the groovy-integration profile will not be activated as usual.
However, you can always navigate to the test folder, click "Run 'Tests in '...''" and have all the benefits brought to you by IntelliJ.
Exclude gmavenplus-plugin within IntelliJ IDEA takes one more advantage, IntelliJ IDEA sometimes add the generated test stubs as Sources instead of Test Sources, and unable to compile them due to lack of test-scoped dependencies.
I too get the message saying that my groovy class already exists. What I discovered is that it occurs after I Make Project the first time. From then on that error always occurs. If you want to get rid of the error, all you have to do is to delete the jar file produced stored in the app/build/libs directory. And of course, if you re Make Project again, the error comes back. So it's kind of tripping over itself by including it's own output jar lib in detecting that error.
I think its just a nuisance error and it doesn't seem to mess things up. It's certainly annoying to get an error indication when you don't have anything wrong. Perhaps there's someway to prevent this bogus error with some kind of groovy lint option, etc.; I just don't know. I would think that Michel solution of excluding certain files like the output lib file would work. The lack of good, reliable and consistent documentation concerning groovy and gradle builds makes me not interested in wanting to solve this problem; especially since it appears to just be a nuisance error.
Here's a little update. I did solve the problem, but I'm not exactly sure what the exact sequence you need to do to solve it. The best I can do is to explain the things that I dinked with. My solution seems to be centered around the solution posted at "Class already exists" error in IntelliJ on Groovy class . They talk about excluding a file from IntelliJ. I'm using Android Studio 3.1.3 and I couldn't exactly find a way to do what they where saying in that post. If I went into the Project tab and seletected Project Files I was able to navigate to my build folder. That directory was already marked as excluded. I did toggle it to being included and then back to being excluded. That did not seem to fix the problem. I then noticed that one could also load/unload modules. If I unloaded in my case the 'app' module and clicked okay, the error about the class already existing went always. However, the class file still thought their was an error. In other words, the class file name in the tab still had a squiggle line underneath it's name. Note however, there were no lines in error in the actually class file. I then played around with various attempts of unloading and loading of Modules executing them positioned at various other places in the directory file structure and cleaning the project. At the end, I just left things in the state where every module was loaded. I then closed the Android Studio project and reopened it. What I noticed was that the in Project Files tab, I could no longer see or navigate to the build directory as I previously could. And more importantly, the error about the class already existing went away. So something in the sequence of things I dinked with fixed the problem, but it didn't take affect until I closed Android Studio and restarted it. I've noticed in other situations where Android Studio need to be close and restarted to actually correct itself.
Related
I personally prefer to keep my coding problem off of here unless I think I'm stumped. I'm trying to add the mysql java dependency to my project (I'm coding a Minecraft-Spigot 1.12.2 plugin).
I've been coding MySQL for years but I've never had to use it with Java until now so I'm following this tutorial: https://www.spigotmc.org/wiki/connecting-to-databases-mysql/
Which redirected me to this page: https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.26
Naturally adding a Maven dep is easy enough you just copy and paste it! Beyond that, I'm not very in tune with the inner workings of the system.
Whenever I compile (it does in-fact compile without throwing any fits) and upload it to my servers I get this error: java.lang.NoClassDefFoundError: com/mysql/cj/jdbc/MysqlDataSource. Now, I know that this has to do with the class being undefined or something. So obviously, I searched the error code. A lot of the problems I saw didn't seem to apply to me.
I double checked and I DO see mysql-connector-java inside of my "External Libraries" section in my IDE (InteliJ IDEA)
I also saw some people sending this link: How can I create an executable JAR with dependencies using Maven?
Which, the answer didn't seem to help me out either (unless I missed something).
My hope is that by sending my file someone can help me out here?
I've seen some people mention that it could be a problem with a classpath? How exactly can I go about fixing that (if it is the problem). I couldn't seem to find anything to help me with that problem (tho in this case classpath is a little over my head. Def want to read up on it more in the future).
Here's my pom.xml any helpful assistance is appreciated!
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>example</artifactId>
<version>1.12.2-SNAPSHOT</version>
<packaging>jar</packaging>
<name>example</name>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
</dependencies>
</project>
Did you use the right SNAPSHOT jar? Because that should work for you and
jar tf <the snapshot>.jar | find "com/mysql/cj/jdbc/MysqlDataSource"
on Windows or
jar tf <the snapshot>.jar | grep "com/mysql/cj/jdbc/MysqlDataSource"
on *nix should find that 'missing' class in the jar
I have an API that I'm trying to rewrite that uses the old swagger-maven-codegen 2.3.1 with a legacy version of Spring 1.5.9. I can see that when I run mvn package or mvn install , the plugin generates the interfaces that all the Controllers implement. All of this is of course defined in swagger.yaml file.
I followed the swagger codegen instructions per their github repo (https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen-maven-plugin) and it simply states to add it to the build -> plugins section of the pom.xml. So, this works fine with the codegen version 2.3.1 that they use in their example, but does NOT work with version >= 3.0.0. Now, you might tell me "hey just use 2.3.1 then" but I want to use openapi spec 3, which upon my research has to have swagger codegen version >= 3.0.0. Reference:
How to fix java.lang.RuntimeException: missing swagger input or config?
Now, normally you just update the plugin version in the pom, but for some reason, my code never compiles or runs when I use a plugin version of >= 3.0.0. I get this error message in intelliJ:
The POM for io.swagger:swagger-codegen-maven-plugin:jar:3.0.0 is missing, no dependency information available
So they led me to maybe believe my group, artifact or repo was wrong, so I started trying to find on the mavencentral URL the exact path of this JAR, and I did notice that I didn't see any version for 3.X.X except these two-variants of 3.0.0-rc0 and 3.0.0-rc1, which you can see here:
https://repo1.maven.org/maven2/io/swagger/swagger-codegen-maven-plugin/
Lo and behold, when I tried 3.0.0-rc1 in my pom version, my code started compiling. I do have sample swagger api.yaml file that I am reading in (very basic just for testing), and then I started seeing now okhttp packages missing or that I missing that in my pom. However, I do see it attempting to generate the server stub in the /target output direct that I defined in my pom.xml configuration for the plugin, so that is good:
So I guess my questions at this point to summarize aka TL;DR are:
what is the openapi I should be using - 2 or 3? 3 is newer, so I figured this was obvious
if it is openapi 3, how do I use this with swagger codegen plugin version >= 3 in my pom? why can't I resolve the dependency? is my lacking understanding of dependencies vs plugin dependencies here, hurting me?
when I do put in this 3.0.0-rc1 swagger codegen version, why am I getting all these okhttp errors? Is there a guide somewhere to show the END-TO-END complete setup needed to use this plugin?
even in my old code, The #Controllers are implementing Interfaces that get generated in the /target directory. I don't see their interface names defined in the swagger.yaml so I'm wondering what design pattern this is OR where in the swagger documentation are these instructions?
Anyway, so yes, if someone could please help me out or explain some of these things or point me to an article that actually shows how to get an API up using swagger codegen from beginning to end , I would greatly appreciate it!
My pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mydomain.me</groupId>
<artifactId>my-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>My API</name>
<description>Version 2.0 of my API</description>
<properties>
<java.version>11</java.version>
</properties>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven Central</name>
<layout>default</layout>
<url>https://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.swagger.codegen.v3</groupId>
<artifactId>swagger-codegen-cli</artifactId>
<version>3.0.25</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>3.0.0-rc1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
<output>${project.basedir}/target/generated-sources</output>
<language>java</language>
<configOptions>
<sourceFolder>src/gen/java/main</sourceFolder>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I can also share my swagger.yaml if you would like to see that.
I've got several github java projects. One of them I've manually deployed to sonatype's repository so that it gets published in maven central.
This has been a somewhat painful process in the sense that it seems to involve too many hoops to jump through and a lot of manual work and I'd like to automate that.
So I actually stopped doing that because it was just too much work. There's plenty of documentation that suggests this is possible and quite a bit that suggest that it somehow involves doing something with the nexus-staging-maven-plugin.
Unfortunately all of that documentation is (in typical maven style) skipping over the essential details that would allow me to figure out in a straightforward way the minimum amount of steps necessary that allow me to automatically publish release builds to the sonatype repository (i.e. without me manually approving things).
So, what is the blurb that needs to be present in my pom (assume a otherwise bog standard uncomplicated java project), including urls for the sonatype repository, all documentation I've found seems to insist localhost:8081 is it, and the required maven incantations to make it do a release (preferably via the mvn release plugin), have it sign the artifacts, and have it deploy the resulting artifacts to sonatype, approved and all ready to be synced to maven central, etc.
So, I'm sort of looking for the maven replacement of a "gem push" in the ruby world, which gets the job done in a convenient one liner. It's a simple case of given a jar file approved by me, how do I get it to end up in maven central with the least amount of fuss.
I'd very much appreciate some examples of pom files already setup to do this that I can copy and adapt.
Edit:
Here's my working pom file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jillesvangurp</groupId>
<artifactId>jsonj</artifactId>
<version>1.34-SNAPSHOT</version>
<name>JsonJ</name>
<description>A framework for working with json in Java the "proper" way. No mappings or model classes, it's all just lovely json, but in Java.</description>
<url>https://github.com/jillesvangurp/jsonj</url>
<licenses>
<license>
<name>MIT license</name>
<url>https://github.com/jillesvangurp/jsonj/blob/master/LICENSE</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git://git#github.com:jillesvangurp/jsonj.git</url>
<connection>scm:git:git#github.com:jillesvangurp/jsonj.git</connection>
<developerConnection>scm:git:git#github.com:jillesvangurp/jsonj.git</developerConnection>
</scm>
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<snapshotRepository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>sonatype-nexus-staging</id>
<name>Nexus Release Repository</name>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<developers>
<developer>
<id>jillesvangurp</id>
<name>Jilles van Gurp</name>
<url>http://www.jillesvangurp.com</url>
<timezone>gmt+1</timezone>
<roles>
<role>Main Developer</role>
</roles>
</developer>
</developers>
<organization>
<name>www.jillesvangurp.com</name>
<url>http://jillesvangurp.com</url>
</organization>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8.1</version>
<executions>
<execution>
<id>documentation</id>
<phase>prepare-package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>gathersource</id>
<phase>prepare-package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6</version>
<extensions>true</extensions>
<configuration>
<!-- The Base URL of Nexus instance where we want to stage -->
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<serverId>sonatype-nexus-staging</serverId>
</configuration>
</plugin>
</plugins>
<extensions>
<extension>
<artifactId>wagon-webdav-jackrabbit</artifactId>
<groupId>org.apache.maven.wagon</groupId>
<version>2.2</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<mavenExecutorId>forked-path</mavenExecutorId>
<useReleaseProfile>false</useReleaseProfile>
<arguments>-Psonatype-oss-release</arguments>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>sonatype-oss-release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.7</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<exclusions>
<exclusion>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>xom</groupId>
<artifactId>xom</artifactId>
<version>1.2.5</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.jillesvangurp</groupId>
<artifactId>efficientstring</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
</dependencies>
</project>
The comment (#aurelien-thieriot) below put me on the right track but was not enough by itself.
In the end I took the sonatype parent pom and flattened it into my pom file.
This allows me to use the mvn release plugin normally. It uploads the artifacts to the sonatype staging repository. Then to release the artifacts, I actually needed the staging repository id.
You can find this from the repositories view in https://oss.sonatype.org/index.html#stagingRepositories.
In my case the command line became:
mvn nexus-staging:release -Ddescription="Release 1.33" -DstagingRepositoryId=comjillesvangurp-1002
Without the right id it doesn't figure it out and still fails: Sonatype Maven Staging Plugin Issue
So 95% automated but I still need to figure out the stagingRepositoryId every time.
Edit:
mvn release:perform actually tells you the id of the staging repository.
I guess you could write a script that extracts this id from the output and then passes it in to the next step. If somebody knows some mvn voodoo to make mvn release:perform do the staging release as well, it would be much appreciated.
For the convenience of Maven projects, Sonatype is providing a parent POM you can add to your project with all the basic configuration:
https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-Changesto%7B%7Bpom.xml%7D%7D
The important bits are:
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
And the source code repository details:
<scm>
<connection>scm:svn:http://foo.googlecode.com/svn/trunk/</connection>
<developerConnection>scm:svn:https://foo.googlecode.com/svn/trunk/</developerConnection>
<url>http://foo.googlecode.com/svn/trunk/</url>
</scm>
You will also need GPG to be install on your computer (Required to sign the packages) and our settings.xml correctly filled with your credentials:
<servers>
<server>
<id>sonatype-nexus-snapshots</id>
<username>your-jira-id</username>
<password>your-jira-pwd</password>
</server>
<server>
<id>sonatype-nexus-staging</id>
<username>your-jira-id</username>
<password>your-jira-pwd</password>
</server>
</servers>
After that, you should be able to use the two steps release:
$ mvn release:prepare
$ mvn release:perform
Unfortunately, I don't know any way of automate the manual approval part of the process (In oss.sonatype.org). But that should already save you some times.
The documentation, as shown above, is probably a bit convoluted but is very complete and gives you all you need to know for various scenarios.
EDIT:
In fact I think I am wrong and there is a part on automate approval process. Interesting.
And for this part you are right, the details are quite limited. Though, I hope the first part of the configuration already helps you a little bit. I need to look further into this staging stuff (Or maybe someone else would have already done it !)
EDIT_AGAIN:
I need to actually try it but it would sound like something as follow:
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6</version>
<extensions>true</extensions>
<configuration>
<!-- The Base URL of Nexus instance where we want to stage -->
<nexusUrl>https://oss.sonatype.org/service/local/staging/deploy/maven2/</nexusUrl>
<serverId>sonatype-nexus-staging</serverId>
</configuration>
</plugin>
</plugins>
According to the documentation, the deploy should be replaced by the right staging workflow (Including the close) and it would left the latest step:
$ mvn nexus-staging:release -Ddescription="Yippie!"
TO BE TESTED...
So 95% automated but I still need to figure out the stagingRepositoryId every time.
You can use mvn nexus-staging:rc-list
Specifically, by doing mvn release:rc-list and using grep or whatever to filter the output from that by some form of the group ID or other substring that you know the stagingRepositoryId to be, you can determine the full stagingRepositoryId value
For example, the group ID for my project is nu.validator and my stagingRepositoryId values are all in the form nuvalidator-NNNN where the NNNN part is a number that started from 1000 with my first release and that the system increments by 1 each time I release; so nuvalidator-1000, nuvalidator-1001, and so on.
So in the python script I use for my build, I just do this:
output = subprocess.check_output("mvn nexus-staging:rc-list -DnexusUrl=https://oss.sonatype.org/ -DserverId=ossrh")
for line in output.split('\n'):
if "nuvalidator" in line:
stagingRepositoryId = "nuvalidator-" + line[8:23]
...
That's because the relevant lines returned in the mvn nexus-staging:rc-list output are in the form:
...
[INFO] central_bundles-3514 OPEN Implicitly created (auto staging).
[INFO] central_bundles-3515 OPEN Implicitly created (auto staging).
[INFO] central_bundles-3521 OPEN Implicitly created (auto staging).
[INFO] nuvalidator-1008 OPEN Implicitly created (auto staging).
...
My Maven project foo.web has its source files in src/main and the test sources in src/test. Of course, the test classes make use of the "main" classes. Now I want to use the test classes in another project during runtime, so I followed these instructions on how to create a test-jar.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
This works perfectly well, a jar like web-SNAPSHOT-tests.jar is created and I can include it in my other project.
<dependency>
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>test-jar</type>
</dependency>
But it seems like the dependency to web-SNAPSHOT is not correctly set, because at runtime I receive NoClassDefFoundErrors of classes which are available in foo.web. So I added another dependency:
<dependency>
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
Unfortunately, this changes nothing. Does anyone know what is wrong here?
WAR archives are structured differently from JARs. When running in an application server such as Tomcat or JBoss, the server will handle the WAR correctly. Since you are running outside of a server, the artifact will be used like to a normal JAR archive. Because WARs use different locations for the .class files, the NoClassDefFoundError is thrown at run time.
In a JAR, the class com.example.Foo will be stored at /com/example/Foo.class. Since WARs are designed to contain libraries, resources etc. the classes should not be stored relative to the root of the archive. Instead, they are contained in the folder /WEB-INF/classes, Foo would be stored as /WEB-INF/classes/com/example/Foo.class.
Fortunately, the Maven developers thought of this issue and added the attachClasses option to the WAR plugin. This option creates an additional JAR with the classes classifier that contains only the Java classes in JAR format (relative the the archive root).
To enable the building of this JAR, you can use this snippet in your WAR project's build section (in addition to the configuration for the maven-jar-plugin to build the test JAR):
<pluginManagement>
<plugins>
<!-- … -->
<plugin>
<!-- build the classes JAR (non-test classes) -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- … -->
<plugin>
<!-- build the test JAR (test classes) -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Since the classes are attached, they will be installed and deployed by Maven together with the WAR artifact. Note that this only provides you with the contents of the regular WAR archive, to use the test classes, you need to depend on both the classes artifact and the test jar. To do this, you can use:
<dependencies>
<!-- … -->
<dependency>
<!-- test classes only -->
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>test-jar</type>
</dependency>
<dependency>
<!-- non-test classes only -->
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>jar</type>
<classifier>classes</classifier>
<scope>runtime</scope>
</dependency>
</dependencies>
Try:
<dependency>
<groupId>foo</groupId>
<artifactId>web</artifactId>
<version>SNAPSHOT</version>
<type>war</type>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
Maven allows you some configuration regarding snapshots dependancy
<repository>
<id>foo-repository</id>
<url>...</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>XXX</updatePolicy>
</snapshots>
Check the above config. If its false in pom.xml maven will not update snapshots. Also you will find the following thread useful for your query What exactly is a Maven Snapshot and why do we need it?
First off: I'm not a Java coder. I'm new to the Java/Maven tool chain. We're using a Java library for a project which we want to launch as a Heroku background worker.
This project relies on two external libraries, the mongodb Java driver which is available through Maven's central repo, and another third party library. I've seen the Heroku article on "unmanaged dependencies", but something else appears missing, as I get an error like: Could not find the main class: com.company.myproject.MyApp Program will exit. when I try to run the app locally according to Heroku's instructions on "Getting Started with Java".
I noticed that their pom.xml file contains a Maven plugin maven-dependency-plugin to copy dependencies, and when I check my target/classes folder, I don't see any of the dependencies.
Heroku also publishes a guide on building background workers in Java. That pom.xml contains a build assembly plugin, which seems more complex.
I'm a bit lost in all this ceremony (especially coming from Rails), and I'd like to stat with the simplest possible pom.xml to get this running. Is there a Maven archetype file for Java workers on Heroku? I'm also using NetBeans as IDE, and it would be great to use the IDE tools for this, if available, but it's a secondary priority.
Below my pom.xml so far:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myproject</groupId>
<artifactId>myproject</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<name>myproject</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.thirdparty</groupId>
<artifactId>thirdparty</artifactId>
<version>0.2.9</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>project-local</id>
<name>Project-local Repo</name>
<url>file:${project.basedir}/repo</url>
</repository>
</repositories>
</project>
You definitely need to use the maven-dependency-plugin to copy all of the dependencies into the target/dependency directory:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals><goal>copy-dependencies</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then your Procfile needs to include those dependencies in the classpath:
foo: java -cp target/classes:target/dependency/* com.myproject.Main
Where com.myproject.Main is the class name of the Java class you want to run (which must contain a public static void main method. Note that this also adds the Java classes which are compiled from src/main/java into the target/classes dir.