0

Let me start by saying I'm learning Java, and come from the .NET/C# world.

TL;DR: This syntax does not work in VSCode or Eclipse IDE, does in IntelliJ. Why? What am I missing?

    import path.to.class.Foo;
    import path.to.class.Foo_; // cannot be resolved error

...

   Foo_.barID; // cannot resolve to a variable

The underscore_ notation just causes the above errors... ugh

Long version:

I work on an API, and my team is newer to the project. None of us JAVA specific devs, and we've learned a ton over the last several months. The original devs created the project using IntelliJ, and supported it using that IDE. Unfortunately, our IntelliJ licenses keep being allowed to expire and it takes a week to get it back, and I'm not good with down time, so I tried Eclipse and VSCode. When trying to debug, the project won't build because some imports are unable to be resolved, as well as some variables that appear to be using JPA 2.0 notation for Dynamic, typesafe queries. Reading the following, this notation appears to have been around a long time, and Eclipse a long time Java IDE, so I think I'm clearly missing something. What does an underscore concatenated to a class name mean? https://developer.ibm.com/articles/j-typesafejpa/#N102F2 https://developer.ibm.com/articles/j-typesafejpa/

I have a hard time believing this is only possible in IntelliJ, so it has to be something I'm missing within the IDE's. A package, or setting, or something that is not allowing the IDE to utilize the Criteria API?

pom.xml file as requested:

<?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">
    <parent>
        <artifactId>foo-app</artifactId>
        <groupId>foo.bar.app</groupId>
        <version>0.4.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>bar-api</artifactId>
    <name>Public Facing API</name>

    <properties>
        <mainClass>foo.bar.fib.api.ApiService</mainClass>
        <jjwt.version>0.11.4</jjwt.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>foo.bar.fib</groupId>
            <artifactId>fib-testing</artifactId>
            <version>0.4.0-SNAPSHOT</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-client</artifactId>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-migrations</artifactId>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-hibernate</artifactId>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-auth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.hubspot.dropwizard</groupId>
            <artifactId>dropwizard-guicier</artifactId>
        </dependency>
        <dependency>
            <groupId>${typesafe.config.groupID}</groupId>
            <artifactId>typesafe-dropwizard-configuration</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>foo.bar.fib</groupId>
            <artifactId>fib-queue</artifactId>
            <version>0.4.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>foo.bar.fib</groupId>
            <artifactId>fib-common</artifactId>
            <version>0.4.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>foo.bar.fib</groupId>
            <artifactId>fib-tokens</artifactId>
            <version>0.4.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>foo.bar.fib</groupId>
            <artifactId>fib-buttonstuff</artifactId>
            <version>0.4.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>${hapi.fhir.groupID}</groupId>
            <artifactId>hapi-fhir-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.jakewharton.fliptables</groupId>
            <artifactId>fliptables</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>${bouncey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>${bouncey.version}</version>
        </dependency>
        <dependency>
            <groupId>${hapi.fhir.groupID}</groupId>
            <artifactId>hapi-fhir-structures-r4</artifactId>
        </dependency>
        <dependency>
            <groupId>${hapi.fhir.groupID}</groupId>
            <artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.helger</groupId>
            <artifactId>ph-schematron</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>${jjwt.version}</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>${jjwt.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>${jjwt.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
            <version>2.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>
        <dependency>
            <groupId>com.newrelic.agent.java</groupId>
            <artifactId>newrelic-java</artifactId>
            <version>${newrelic.agent.version}</version>
            <type>${newrelic.agent.type}</type>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-json-logging</artifactId>
        </dependency>
        <!--Test resources-->
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-testing</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
            <version>2.31</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>javax.servlet-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>${project.basedir}/../src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <directory>${project.basedir}/../src/main/resources</directory>
            </testResource>
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <configuration>
                    <createDependencyReducedPom>true</createDependencyReducedPom>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>${mainClass}</mainClass>
                        </transformer>
                    </transformers>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                    <shadedArtifactAttached>true</shadedArtifactAttached>
                    <finalName>${project.artifactId}</finalName>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${mainClass}</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <configuration>
                    <container>
                        <args>
                            <arg>server</arg>
                        </args>
                        <ports>
                            <port>8080</port>
                        </ports>
                        <environment>
                            <DB_MIGRATION>1</DB_MIGRATION>
                        </environment>
                        <entrypoint>/entrypoint.sh</entrypoint>
                    </container>
                    <extraDirectories>
                        <paths>
                            <path>${project.basedir}/../bbcerts</path>
                            <path>${project.basedir}/target/jacoco-agent</path>
                            <path>${project.basedir}/docker</path>
                            <path>${project.basedir}/../src/main/resources/keypair</path>
                            <path>${project.basedir}/target/newrelic-agent</path>
                        </paths>
                        <permissions>
                            <permission>
                                <file>/entrypoint.sh</file>
                                <mode>755</mode>
                            </permission>
                        </permissions>
                    </extraDirectories>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <annotationProcessorPath>
                            <groupId>org.hibernate</groupId>
                            <artifactId>hibernate-jpamodelgen</artifactId>
                            <version>5.4.2.Final</version>
                        </annotationProcessorPath>
                        <path>
                            <groupId>javax.xml.bind</groupId>
                            <artifactId>jaxb-api</artifactId>
                            <version>2.3.0</version>
                        </path>
                        <path>
                            <groupId>javax.annotation</groupId>
                            <artifactId>javax.annotation-api</artifactId>
                            <version>1.3.1</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

EDIT: No longer monitoring this question since using the Community Edition of IntelliJ IDEA will work for my needs and I do not have to switch IDE's. I think the proposed answer will work for some, if not most; however, since I was unable (and unwilling to continue) to make the build work with another IDE I am leaving it unselected as the solution.

jeffcodes
  • 726
  • 2
  • 8
  • 20
  • I think that are **JPA model classes**. They abstractly model the database table classes, w.r.t. entities & criteria API. These are _generated_ classes. Maybe the generation is hidden in a maven/gradle phase during the normal build. The class paths might be incomplete. In that case you might opt to have a separate build of a library to generate these classes, and have a normal dependency on the library. Sometimes during database maintenance you will need to an extra build step but fine. – Joop Eggen Nov 01 '22 at 14:25
  • 1
    Edit the question to include the project's pom file (if using Maven) or build.gradle file (if using Gradle); there is likely a step in there that generates those metamodel classes, and we need to know how that's configured. – E-Riz Nov 01 '22 at 14:28
  • BTW does the IntelliJ Community edition not work to bridge the license gap (with less features)? And are licenses not cheaper when no gap? – Joop Eggen Nov 01 '22 at 14:29
  • @JoopEggen I'll check into community edition. I figured these could be generated classes, I just don't get why other IDE's wouldn't build them. Especially, one that is Java specific. – jeffcodes Nov 01 '22 at 14:59
  • @E-Riz Provided pom file. – jeffcodes Nov 01 '22 at 14:59
  • @JoopEggen IntelliJ CE will bridge the gap. Still, I'd really like to understand why this is happening, and how to correct it. If not for me, for the community at large. Thanks! – jeffcodes Nov 01 '22 at 15:31

2 Answers2

0

Those are so-called metamodel classes for your entities, and they are generated by Hibernate (since you have the hibernate-jpamodelgen annotation processor configured in the pom). So whenever a maven build is run, those classes are generated to a specific directory, and then Maven includes that directory with as a source location during the compile step.

Since Eclipse (and VSCode, I presume) aren't aware of this folder of generated files as a source location for the project, it doesn't recognize the generated classes. There are a couple of ways to deal with it:

  1. You can configure the annotation processor in Eclipse so that it does the same thing as the Maven plugin. It's pretty straightfoward, but requires a one-time manual setup. A decent set of instructions is found here; the official JBoss Hibernate instructions are pretty dated, but might still be valid, found here (there's also a decent explanation of Hibernate's metamodel generation on that page, for reference).

  2. You can rely on Maven to run the generator and just add the output folder as a source location to your Eclipse project. The default output location for APT-generated files in Maven is "target/generated-sources/apt", so you can add that to the Eclipse project's Build Path as a source folder. You can do that in the project's Properties, Java Build Path section; or just right-click on the folder and select Build Path > Use as Source Folder enter image description here.

Note that with option 2, when you change your entities you'll have to re-run the maven build (at least generate-sources phase) to see the updated generated classes.

E-Riz
  • 31,431
  • 9
  • 97
  • 134
  • The files are .java files not .jar files... so #1 does not work. I'll have to put some time in tomorrow to #2. Still no dice on VSCode. @E-Riz – jeffcodes Nov 01 '22 at 19:47
  • I can add the .java files, but I'll need to play with this more tomorrow. Promising, and still headache inducing. Probably not even worth the time given I can use CE as a bridge. – jeffcodes Nov 01 '22 at 19:58
  • I think you're misunderstanding. The JAR(s) you would add as annotation processor(s) would not be what's _generated_, it's the processor(s) that do the _generating_. – E-Riz Nov 02 '22 at 13:44
  • I agree it's harder than it should be, but very doable. Many projects use annotation processors to generate code. The second option is easier to set up, and as long as your entities don't change often it's not really so inconvenient to have to run the maven build when they do. – E-Riz Nov 02 '22 at 13:45
  • I have no issues with Maven doing it's thing. I, overall, do not understand all of the nuances of Java and Maven to understand why one IDE does this seamlessly, and the others do not. Given I can use CE to bridge my gap, I'm not putting in more effort since our Java code is going to also be replaced anyway. I'll likely just close this question soon – jeffcodes Nov 03 '22 at 14:17
0

Use the Community Edition of IntelliJ as offered by @joopeggen. Proposed answer by @e-riz is a likely secondary answer.

jeffcodes
  • 726
  • 2
  • 8
  • 20