intellij not picking up maven project structure - maven

I have a mavenized java project in Intellij 122.327. Unfortunately (due to legacy code) certain code in the src directory uses tests in the test directory. I'm trying to remove these dependencies but its a long shot. In the meanwhile, I'm able to compile and deploy by using the build-helper maven plugin and adding src/test/java as sources:
<execution>
<id>add-test-dir-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/java</source>
</sources>
</configuration>
</execution>
Problem is whenever I restart Intellij it keeps marking the src/test directory as a "test" directory (if I go to Project Structure -> Modules -> Sources, src/test is marked in green). So every time I have to manually mark test/java as "Sources". Is there a way to permanently mark this as sources? Even better, does Intellij have a way to read from the pom and infer the project structure?

Check the logs for any related exceptions. There can be many reasons for this problem like a proxy with the self signed certificate, invalid VM options, network issues, etc. See also this answer.
If the issue persists, contact support with the logs attached.

Related

Why can't my local environment find generated Proto classes?

I have a project that is set up to compile protobufs specified in my resources directory. To that end, I am using the xolstice plugin, with the following configuration:
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
</plugin>
This is roughly the configuration described here. The protos in question include a few object models as well as a GRPC service which I register for use.
The .jar is packaged easily enough, with a maven-jar-plugin I've inherited from our common root pom. The configuration for that is:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
When I run my project in IntelliJ, everything seems to work fine - I can observe that the required protos are generated correctly and I don't have any issues. However, when I run the .jar with java -jar target/service.jar, I run into the following issue:
[Byte Buddy] ERROR com.artistchooser2.handlers.ChooseArtistsHandler [jdk.internal.loader.ClassLoaders$AppClassLoader#5c29bfd, unnamed module #776b83cc, Thread[main,5,main], loaded=false]
java.lang.IllegalStateException: Cannot resolve type description for com.artistChooser2.v1.ChooseArtistsServiceGrpc$ChooseArtistsServiceImplBase
at net.bytebuddy.pool.TypePool$Resolution$Illegal.resolve(TypePool.java:161)
at net.bytebuddy.pool.TypePool$Default$WithLazyResolution$LazyTypeDescription.delegate(TypePool.java:1038)
The class which should have been generated by the protocol compilation step seems nowhere to be found. Interestingly, however, I can easily confirm that this seems to be broken by running: jar -tvf target/service.jar |grep 'ChooseArtistsServiceGrpc$ChooseArtistsServiceImplBase'. If I run that, I can observe that the class IS actually available and correctly packaged with the .jar. I can also verify that in IntelliJ easily enough by perusing through everything within the .jar.
I noticed this issue because I was setting up a test that runs my service in a Docker image and verifies that it starts up correctly, as it would in production. Interestingly, however, although I am locally unable to get mvn verify to run successfully, my build server (which I have confirmed is running mvn verify) runs to completion without issue.
I've checked all of the usual suspects - it has nothing to do with the maven build profile that is used on the build server, maven versions are the same on the build server and locally, I've even tried clearing the .m2/repository in case there was something fishy there.
So I guess my question is whether anyone has any further leads? Is there something else I should be looking into, some sort of environment variable, or anything else that might cause the above exception locally but not on a build server?
So I'm still not entirely sure how exactly this issue manifested - in my .proto spec, I had:
option java_package = "com.artistChooser2.v1";
Interestingly, on my local machine, when I found the compiled protos in the packaged .jar, they were appearing under com.artistchooser2.v1. Note the lowercase 'c'. But the test I was running was still looking in the upper 'C' package.
For some reason, on the build server, they were actually compiling in the correct location, but not on my local jar. I'm running a Mac, while the build server is a Linux box. Curious if it has something to do with the environment.
Either way, the solution was to alter the package name to what my machine was expecting, which was the lower 'c', probably a better package name anyway.

GWT-Maven only compile gwt.rpc

I have a situation where I am debugging via -noserver and it forces me to recompile my gwt application everytime one of my RPC objects changes or I get a serialization error (This is well described in the GWT documentation and I understand why it is happening).
That being said, our project is getting quite big and the compile takes a while to complete, which is slowing down our development process. I have optimzed this as much as I can (Using -draftCompile, only doing a single permutation, and skipping all tests) but it's still pretty slow and I have a pretty beastly computer.
This led me to wonder if a better option here would be to get the compiler to only output the necessary files to make serialization work correctly.
Anyone know if this is possible?
Thanks!
You can do it using maven goals.
In Eclipse "run configurations" I have a specific configuration for that.
Goals: gwt:generateAsync gwt:i18n gwt:css
Profiles: dev-ff
The gwt:generateAsync goal is for generating your RPC. This is a standard goal with gwt-maven-plugin (assuming you are using it, of course).
Profiles: dev-ff ensures I'll only generate the code for Firefox.
Here is a part of the maven plugin config. Notice the goals definitions. You'll at least need the servicePattern attribute to tell the plugin where are your RPC interfaces.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>${gwt-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
<goal>i18n</goal>
<goal>css</goal>
<goal>generateAsync</goal>
</goals>
</execution>
</executions>
<!-- Plugin configuration. There are many available options, see gwt-maven-plugin
documentation at codehaus.org -->
<configuration>
<servicePattern>**/*RPC.java</servicePattern>
</configuration>
</plugin>
After doing this kind of operation, I often had to open my generated async files to get them in sync with Eclipse. Afterwards we found out we could just delete the gwt-unitCache/ folder in the target/ folder to force the application to use the new RPC classes.
More information about the plugin is available here.

Eclipse Maven multi module project with xmlbeans

I have a multi module project, in which one of the module ( say MODULE-A) generates sources and classes using xmlbeans plugin. So everytime when I do a clean install of parent project, eclipse recognizes all of the generated sources as new classes, and I don't want to commit the same files again and again when there is no schema change. To overcome this problem, I wrapped xmlbeans build under a profile so that I can build it with profile whenever there is a schema change. But it didn't solve the problem completely.
Whenever I try to do clean build of parent, MODULE-A is not creating 'schemaorg_apache_xmlbeans' under build directory ( which is something only generated by xmlbean plugin when I run with profile ). I can tell maven to exclude 'schemaorg_apache_xmlbeans' from the clean task. But I want to know if this is the right way to handle.
Appreciate your responses.
Thanks in advance
One alternative to this approach is to add this plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
This will allow the generated-sources to be added as a source folder so every time it generates you will have them built and available. You wouldn't commit these but when the actual jar gets built/released they will be in there and work all the same. This allows you to always be using code most up to date with your schema. This may not be the best solution for you but I found it to be a good idea when I ran into a similar situation.

define additional source directory in maven

I generate Java sources from a wsdl file. These sources are not under version control (but the wsdl is). We use the cxf-codegen-plugin in maven and the generated classes are generated in <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>.
This works all fine in maven.
I have to define this directory as addition source directory in Intelij Idea. (targetis normaly excluded).
But every time I re-import the maven project into InteliJ Idea (due to pom changes), I have to manually edit the project structure in Idea and redefine the addition source directory.
Is there any way I can either define this aditional source directory in maven, so Idea picks it up on reload, or tell Idea not to forget the manual source directoy definition?
This case is described in the IntelliJ IDEA Maven FAQ, Generated Sources section:
Specify the directory of your source root when you reimport a project.
You can select one of the following options:
Detect automatically This is a default option. When you select this option, IntelliJ IDEA automatically detects the location of the generated sources. IntelliJ IDEA also detects which directory to mark as a source root. However, IntelliJ IDEA searches for the generated sources only in target/generated-sources and target/generated-sources/* directories.
target/generated-sources This option enables you to mark the directory as source root manually.
subdirectories of "target/generated-sources" This option enables you to mark a subdirectory as a source root manually.
Don't detect This option lets you skip the detection process.
Take a look at the <add-source> build goal (see an example here)
Quote:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>add-wsdl-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src-generated/src</source>
</sources>
</configuration>
<!-- [...] -->
</execution>
</executions>
</plugin>
You could define the (external) source directory as an dependency to your module. Project Structure -> Modules -> Depenencies. There you have to add a new JAR or Directory dependency.

maven can't add files in generated-sources for compilation phase

I use Apache Thrift to generate code in target/generated-sources.
The Thrift compiler produces a directory named gen-java which contains all the Java code. When I execute mvn compile, the code is generated correctly in target/generated-source/gen-java, but in compilation phase, it complains can't find the classes which defined in gen-java.
In my understanding, Maven 2 automatically adds generated sources, is that right?
And what if my testing code also depends on the generated-sources, do I have to manually specified the compiler includes?
In my understanding, maven 2 automatically add generated sources, is that right?
Nothing automatic, plugins generating source code typically handle that by adding their output directory (something like target/generated-sources/<tool> by convention) as source directory to the POM so that it will be included later during the compile phase.
Some less well implemented plugins don't do that for you and you have to add the directory yourself, for example using the Build Helper Maven Plugin.
And since you didn't provide any POM snippet, any link, I can't say anything more.
And what if my testing code also depends on the generated-sources, do I have to manually specified the compiler includes?
As I said, generated sources are usually added as source directory and compiled and are thus available on the test classpath without you having to do anything.
Generated sources are not compiled or packaged automatically. Some IDEs (i.e. IntelliJ) will however show them as source folders.
To make generated sources visible to maven add a add-source-step to the build/plugins node of your pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/gen-java</source><!-- adjust folder name to your needs -->
</sources>
</configuration>
</execution>
</executions>
</plugin>

Resources