-4

I have searched Stackoverflow for an answer to this question, but the only answer I can find (here) does not work (I added the hibernate-jpa and it makes no difference).

Here is a link to the source code for this project on GitHub. As well, here are the main files in question.

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>ca.thirdgear</groupId>
  <artifactId>healthmonitor</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>healthmonitor</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>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.39</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.2.7.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.3.4.Final</version>
    </dependency>

  </dependencies>

  <build>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <archive>
                        <manifest>
                            <mainClass>ca.thirdgear.healthmonitor.SystemMonitor</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>ca.thirdgear.healthmonitor.SystemMonitor</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
        <resources>
        <resource>
            <directory>src/main/resources/META-INF</directory>
        </resource>
    </resources>
  </build>

</project>

persistence.xml @ src/main/resources/META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">

  <persistence-unit name="healthmonitor" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>ca.thirdgear.healthcheck.entities.User</class>
    <class>ca.thirdgear.healthcheck.entities.TwilioAccount</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.1.172:3306/HomeAutomation" />
      <property name="javax.persistence.jdbc.user" value="root" />
      <property name="javax.persistence.jdbc.password" value="xxxxxxxxxxxxxxxx" />
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
    </properties>
  </persistence-unit>
</persistence> 

main class:

package ca.thirdgear.healthmonitor;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import entities.User;

public class SystemMonitor 
{

    public static void main(String[] args) 
    {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("healthmonitor");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();

        List<User> users = em.createNamedQuery("User.findAll", User.class).getResultList();

        for(User u : users)
        {
            System.out.println(u.getFirstName());
        }


        em.getTransaction().commit();
        em.close();
        emf.close();        
    }

}

User entity class:

package entities;

import java.security.Principal;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;


@Entity
@Table(name = "AuthenticatedUsers")
@NamedQueries(
        {
            @NamedQuery(name = "User.findByEmail",
                    query = "SELECT u FROM User u WHERE u.email = :email"),

            @NamedQuery(name = "User.findByEmailAndPassword",
                query = "SELECT u FROM User u WHERE u.email = :email AND u.password = :password"),

            @NamedQuery(name = "User.findByPassword",
                query = "SELECT u FROM User u WHERE u.password = :password"),

            @NamedQuery(name = "User.findAll",
                query = "SELECT a FROM User a")
        }
)


/**
 * Defines an Authenticated application User.
 */
public class User implements Principal
{
    //PK for entity
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "email", nullable = false)
    private String email;

    @Basic(optional = false)
    @NotNull
    @Column(name = "firstName", nullable = false)
    private String firstName;

    @Basic(optional = false)
    @NotNull
    @Column(name = "lastName", nullable = false)
    private String lastName;

    @Basic(optional = false)
    @NotNull
    @Column(name = "phoneNumber", nullable = false)
    private String phoneNumber;

    @Basic(optional = false)
    @NotNull
    @Column(name = "role", nullable = false)
    private String role;

    @Basic(optional = false)
    @NotNull
    @Column(name = "password", nullable = false)
    private String password;

    @Basic(optional = false)
    @NotNull
    @Column(name = "activeStatus", nullable = false, length = 1)
    private String activeStatus;

    //default constructor
    public User() 
    {
        //not used
    }

    //constructor
    public User(String firstName, String password, String role) 
    {
        this.firstName = firstName;
        this.password = password;
        this.role = role;
    }

    public String getEmail()
    {
        return email;
    }

    public void setEmail(String email)
    {
        this.email = email;
    }

    public String getFirstName()
    {
        return firstName;
    }

    public void setFirstName(String firstName)
    {
        this.firstName = firstName;
    }

    public String getLastName()
    {
        return lastName;
    }

    public void setLastName(String lastName)
    {
        this.lastName = lastName;
    }

    public String getPhoneNumber()
    {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber)
    {
        this.phoneNumber = phoneNumber;
    }

    public String getRole()
    {
        return role;
    }

    public void setRole(String role)
    {
        this.role = role;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public String getActiveStatus()
    {
        return activeStatus;
    }

    public void setActiveStatus(String activeStatus)
    {
        this.activeStatus = activeStatus;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(this.firstName, this.lastName, this.phoneNumber,
                this.email, this.role, this.password, this.activeStatus);
    }

    @Override
    public String toString()
    {
        return "User{" + ", firstName=" + firstName
                + ", lastName=" + lastName
                + ", phoneNumber=" + phoneNumber
                + ", email=" + email
                + ", role=" + role
                + ", password=" + password
                + ", activeStatus=" + activeStatus;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) 
        {
            return true;
        }

        if (obj == null) 
        {
            return false;
        }

        if (getClass() != obj.getClass()) 
        {
            return false;
        }

        final User other = (User) obj;
        return Objects.equals(this.firstName, other.firstName)
                && Objects.equals(this.lastName, other.lastName)
                && Objects.equals(this.phoneNumber, other.phoneNumber)
                && Objects.equals(this.email, other.email)
                && Objects.equals(this.role, other.role)
                && Objects.equals(this.password, other.password)
                && Objects.equals(this.activeStatus, other.activeStatus);
    }

    /**
     * Method implementation from Principal interface.
     *
     * @return The name of the Principal.
     */
    public String getName() {
        return firstName;
    }
}

At this point, all I care about is reading a few attributes from one entity and printing it to the commandline. When I execute my jar file, I get the following stacktrace.

MikesMBP:target Mike$ java -jar healthmonitor-0.0.1-SNAPSHOT.jar 
Exception in thread "main" java.lang.NoClassDefFoundError: javax/persistence/Persistence
    at ca.thirdgear.healthmonitor.SystemMonitor.main(SystemMonitor.java:41)
Caused by: java.lang.ClassNotFoundException: javax.persistence.Persistence
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

Is my persistence.xml file incorrect? Is it my POM file? Is there some configuration I am missing? I am truly stumped by this as I thought this would be a trivial task.

If it matters I am using Eclipse Neon, and I do have Java set up to use SE-1.8.

Thank you.

Community
  • 1
  • 1
mike
  • 137
  • 2
  • 16

2 Answers2

0

Try adding this to your pom.xml:

<!-- https://mvnrepository.com/artifact/javax.persistence/persistence-api -->
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0.2</version>
</dependency>
Viggo Lundén
  • 748
  • 1
  • 6
  • 31
0

The answer to this question lies in the Maven POM file.

The Maven shade plugin is required which then bundles/packages all of the required jar files into the final target jar file. This eliminates the NoClassDefFoundError. This post served as reference to this answer.

Next, the persistence.xml file was explicitly listed as a resource in the POM file. This post served reference.

Here is the updated POM file. Refer to the lower portion for the changes.

<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>ca.thirdgear</groupId>
  <artifactId>healthmonitor</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>healthmonitor</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>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.39</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.2.7.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.4.0.Final</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.1-api -->
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.1-api</artifactId>
        <version>1.0.0.Final</version>
    </dependency>

    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>persistence-api</artifactId>
        <version>1.0.2</version>
    </dependency>

  </dependencies>

  <build>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <archive>
                        <manifest>
                            <mainClass>ca.thirdgear.healthmonitor.SystemMonitor</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <archive>
                        <manifest>

                            <mainClass>ca.thirdgear.healthmonitor.SystemMonitor</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>shade</goal>
                            </goals>
                        </execution>
                    </executions>
            </plugin>   
        </plugins>

        <resources>
            <resource>
                <directory>src/main/resources/META-INF</directory>
                <targetPath>META-INF</targetPath>
                <includes>
                    <include>persistence.xml</include>
                </includes>
            </resource>
        </resources>
  </build>

</project>
Community
  • 1
  • 1
mike
  • 137
  • 2
  • 16