【问题标题】:JUnit BeforeClass causes 'java.lang.ExceptionInInitializerError'JUnit BeforeClass 导致“java.lang.ExceptionInInitializerError”
【发布时间】:2015-11-20 16:03:42
【问题描述】:

我的测试类中有静态变量,我尝试使用静态 @BeforeClass 方法对其进行初始化。但是,我不断收到 java.lang.ExceptionInInitializerError 异常,我无法弄清楚我到底做错了什么。

下面是我的代码 - 我在 setupLocators() 的第一行得到了异常:

package com.stuhrling.warehouse.inventoryTransactions.sales;

import com.stuhrling.warehouse.inventoryObjects.Container;
import com.stuhrling.warehouse.inventoryObjects.InventoryItem;
import com.stuhrling.warehouse.inventoryObjects.InventoryQuantity;
import com.stuhrling.warehouse.inventoryObjects.Location;
import com.stuhrling.warehouse.inventoryObjects.Locator;
import com.stuhrling.warehouse.inventoryTransactions.TransactionStatus;
import java.util.ArrayList;

import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 *
 * @author Mwaldner
 */
public class SaleTest
{

    @SuppressWarnings("unused")
    private static final Logger log = Logger.getLogger(SaleTest.class);

    Sale sale;
    List<InventoryQuantity> inventory;
    List<InventoryQuantity> itemsToRemove;
    private static Locator l1;
    private static Locator l2;
    private static InventoryItem i1;
    private static InventoryItem i2;

    @BeforeClass
    public static void setupTest()
    {
        setupLocators();
        setupItems();
    }

    private static void setupLocators()
    {
        try
        {
            l1 = new Location();
            l1.setCode("L1");
            l2 = new Container();
            l2.setCode("C1");
        }
        catch (Exception e)
        {
            log.error("error",e);
            log.error(e.getStackTrace());
        }

    }

    private static void setupItems()
    {
        i1 = new InventoryItem();
        i1.setBarcode("B1");
        i2 = new InventoryItem();
        i2.setBarcode("B2");
    }

    @Before
    public void setUp()
    {
        setupFakeInventory();
    }

    private void setupFakeInventory()
    {
        inventory = new ArrayList<InventoryQuantity>();

        InventoryQuantity iq1 = new InventoryQuantity();
        iq1.setItem(i1);
        iq1.setLocator(l1);
        iq1.setQuantityOnHand(15);

        InventoryQuantity iq2 = new InventoryQuantity();
        iq2.setItem(i2);
        iq2.setLocator(l2);
        iq2.setQuantityOnHand(35);

        inventory.add(iq1);
        inventory.add(iq2);
    }

    /**
     * <strong>Given</strong><br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a list of <code>InventoryQuantity</code>     <br/>
     * <strong>Then</strong><br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remove said watches at said location from inventory
     */
    @Test
    public void testSellWatches() throws Exception
    {
        try
        {
            sale = new Sale();
            int user = sale.getCreatedBy();
            Date date = sale.getDateTimeFulfilled();

            sale.inventory = inventory;
            SaleLine line1 = new SaleLine(l1, i1, 5);
            SaleLine line2 = new SaleLine(l2, i2, 7);
            sale.add(line1);
            sale.add(line2);
            sale.execute(0);

            assertTrue(checkInventory(l1, i1) == 10);
            assertTrue(checkInventory(l2, i2) == 28);
            assertTrue(sale.getStatus() == TransactionStatus.COMPLETED);
            assertTrue(sale.toString().equals("Sale performed by '' on "));
            assertTrue(line1.toString().equals("Sold 5 of item 'i1' from locator 'l1'"));
            assertTrue(line2.toString().equals("Sold 7 of item 'i2' from locator 'l2'"));

        }
        catch (Exception e)
        {
            log.error(e.getCause());
            log.error(e.getMessage());
            log.error("error", e);
        }
    }

    private int checkInventory(Locator locator, InventoryItem item)
    {
        List<InventoryQuantity> inventory = sale.inventory;

        for (InventoryQuantity iq : inventory)
        {
            if (iq.getLocator().equals(locator) && iq.getItem().equals(item))
            {
                return iq.getQuantityOnHand();
            }
        }

        return 0;
    }

}

这是 Location 类:

package com.stuhrling.warehouse.inventoryObjects;

import com.stuhrling.warehouse.exceptions.LocationsDisabledException;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;

import com.stuhrling.warehouse.exceptions.ParentContainerException;
import com.stuhrling.warehouse.exceptions.PersistenceException;
import com.stuhrling.warehouse.inventoryObjects.Sequence.LocationSequence;
import com.stuhrling.warehouse.inventoryObjects.locationHeirarchy.LocationNameFactory;
import com.stuhrling.warehouse.persistence.WH_HibernateUtil;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

/**
 * @author Brian Horn
 */
@Entity
@DiscriminatorValue("L")
public class Location extends Container
{
    private static final Logger log = Logger.getLogger(Location.class);

    @Column(name = "location_type")
    @Enumerated(EnumType.STRING)
    private LocationType locationType = LocationType.DEFAULT;

    public Location()
    {

    }

    public Location(String code)
    {
        this.code = code;
    }

    public Location(String code, String name)
    {
        this.code = code;
        this.name = name;
    }

    /**
     * Create a new <code>Location</code> for storing inventory;<br>
     * a unique sequence# is automatically assigned to the <code>Location</code>
     * .<br>
     * <Strong>Use this method to create new Locations, <i>do not use the
     * <code>Location</code> class!</i></Strong>
     *
     * @return
     * @throws PersistenceException
     */
    public static Location newLocation() throws PersistenceException
    {
        Location loc = new Location(LocationSequence.getNext());

        return loc;
    }

    /**
     * Create a new <code>Location</code> for storing inventory;<br>
     * a unique sequence# is automatically assigned to the <code>Location</code>
     * .<br>
     * <Strong>Use this method to create new Locations, <i>do not use the
     * <code>Location</code> class!</i></Strong>
     *
     * @param locationType
     * @param parent
     * @return
     * @throws PersistenceException
     * @throws com.stuhrling.warehouse.exceptions.ParentContainerException
     */
    public static Location newLocation(LocationType locationType, Locator parent) throws PersistenceException, ParentContainerException, LocationsDisabledException
    {
        Location loc = new Location(LocationSequence.getNext());
        loc.addTo(parent);
        log.debug(parent.getCode());
        loc.setLocationType(locationType);
        List<Location> siblings = getSiblings(loc);
        LocationNameFactory lFactory = new LocationNameFactory(loc, siblings);
        loc.setName(lFactory.getName());

        return loc;
    }

    @SuppressWarnings("unchecked")
    private static List<Location> getSiblings(Location location) throws PersistenceException
    {
        Session session = WH_HibernateUtil.getCurrentSession();
        List<Location> l = session.createCriteria(Location.class).add(Restrictions.eq("parent", location.getParent())).add(Restrictions.isNotNull("name")).list();
        return l;
    }

    @Override
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public LocationType getLocationType()
    {
        return locationType;
    }

    public void setLocationType(LocationType locationType)
    {
        this.locationType = locationType;
    }

    public void createHierarchicalName(LocationNameFactory factory) throws Exception
    {
        if (!(locationType.equals(LocationType.DEFAULT)))
        {
            name = factory.getName();
        }
    }

    @Override
    public void addTo(Locator locator) throws ParentContainerException, LocationsDisabledException
    {
        if (locator instanceof Location || locator instanceof Subinventory)
        {
            super.addTo(locator);
        }
        else
        {
            throw new ParentContainerException("Cannot add location to container");
        }
    }

}

这里是 StackTrace:

java.lang.ExceptionInInitializerError: null
at com.stuhrling.warehouse.inventoryObjects.Location.<clinit>  (Location.java:17)
at com.stuhrling.warehouse.inventoryTransactions.sales.SaleTest.setupLocators(SaleTest.java:47)
at com.stuhrling.warehouse.inventoryTransactions.sales.SaleTest.setupTest(SaleTest.java:39)

提前感谢您的宝贵时间。

编辑:顺便说一句,我忘了说LocationContainerLocator的子类。 p>

【问题讨论】:

  • 请将完整的异常堆栈跟踪添加到您的帖子中,拜托!当然还有MCVE
  • 变量是否必须是静态的才能在静态 BeforeClass 方法中初始化?
  • 它是静态的,因为设置是静态的(这是由于@BeforeClass)
  • 因此,您的 Location.java 文件的第 17 行显然有异常。它是什么?如果您愿意添加您的 SaleTest.javaLocation.java 文件的完整代码,我们可以更快地为您提供帮助。
  • 如帖子中所述,我在以下位置遇到异常:l1 = new Location() of method setupLocators()。不幸的是,堆栈跟踪没有给我任何更具体的信息。

标签: java junit4


【解决方案1】:

该错误意味着 Java 无法构造 LocationInventoryItem 的实例,因为在 static 代码块中引发了异常。基本上,你有这个:

public class Location {
    static { throw new RuntimeException("Foo"); }
}

或者,更可能的是,

public class Location {
    static Bar BAR = null;
    static Foo FOO = BAR.x(); // NPE

【讨论】:

  • 异常表示有问题,很可能是Location.java:17中的NullPointerException。这条线有什么?您还应该尝试打印完整的堆栈跟踪。 ExceptionInInitializerError 包含另一个异常(原因),它将为您提供更多信息。
【解决方案2】:

如果你使用的是 Mac M1 芯片和 room lib,试试这个:在项目级 build.gradle 中,在 allprojects 中添加以下配置:

allprojects {
repositories {
    // ...
}

// ADD THE FOLLOWING
configurations.all {
    resolutionStrategy {
        force 'org.xerial:sqlite-jdbc:3.34.0'
    }
}

【讨论】:

    猜你喜欢
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 2012-04-16
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    相关资源
    最近更新 更多