0

As the title says, I have a CSV file that will not load from within my web application. I am using Netbeans to build the project.

Whenever I launch the project from Netbeans, it works like it should however when I take the war file and try to deploy it from within the Glassfish interface it shows the variables as undefined which tells me that it is not reading the file. Screenshots below show what is happening and my folder structure.

I have read many posts here and @BalusC has some great information here, but its not working for me and I believe this is somehow my fault, but I need a bit more specific help here than just reading another post.

I have put the CSV file that I am intending to load into the /src/main/resources folder as noted here by BalusC. The code I am using to load the file is as follows.

As a side note, I have a JSP that I am using to check the location and access to the file. The JSP can access and display the file without any problems when the application is deployed manually.

Edit: I ran a debug and could not find anything wrong, so I ran glassfish in verbose mode and loaded the page, once the page was up, it started reading from the file and sending the data but still shows "undefined" in all fields.

Here is the output data from running glassfish in verbose mode.

[#|2017-05-05T16:34:37.609+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=33;_ThreadName=http-listener-1(3);_TimeMillis=1493969677609;_LevelValue=800;|
  Connection open.|#]

[#|2017-05-05T16:34:38.014+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=109;_ThreadName=__ejb-thread-pool3;_TimeMillis=1493969678014;_LevelValue=800;|
  Sent: ABRN / Arbor Realty Trust 7.375% Senior / 25.32 / 25.11 / 25.24 / 12000 / 24.27 / 26.15 / Fri May 05 16:34:38 JST 2017|#]

[#|2017-05-05T16:34:38.016+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=109;_ThreadName=__ejb-thread-pool3;_TimeMillis=1493969678016;_LevelValue=800;|
  Connection closed.|#]

[#|2017-05-05T16:34:38.024+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=34;_ThreadName=http-listener-1(4);_TimeMillis=1493969678024;_LevelValue=800;|
  Connection open.|#]

[#|2017-05-05T16:34:38.029+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=119;_ThreadName=__ejb-thread-pool4;_TimeMillis=1493969678029;_LevelValue=800;|
  Sent: ABT / Abbott Laboratories / 44.01 / 43.60 / 43.65 / 7487400 / 36.76 / 45.84 / Fri May 05 16:34:38 JST 2017|#]

Here is the data for loading the file.

Servlet

@WebServlet(urlPatterns={"/dukeetf"}, asyncSupported=true)
public class DukeETFServlet extends HttpServlet {
private static final Logger logger = Logger.getLogger("DukeETFServlet");
private static final long serialVersionUID = 2114153638027156979L;
private Queue<AsyncContext> requestQueue;
@EJB private PriceVolumeBean pvbean; 

@Override
public void init(ServletConfig config) {
    /* Queue for requests */
    requestQueue = new ConcurrentLinkedQueue<>();
    /* Register with the bean that provides price/volume updates */
    pvbean.registerServlet(this);
}

/* PriceVolumeBean calls this method every second to send updates */
public void send(String ticker, String name, float highPrice, float lowPrice,
float closingPrice, int volume, float fiftyTwoWeekHigh, float fiftyTwoWeekLow,
String currentTime) {
    /* Send update to all connected clients */
    for (AsyncContext acontext : requestQueue) {
        try {
            String msg = String.format("%s / %s / %.2f / %.2f / %.2f / %d /"
                    + " %.2f / %.2f / %s",
                    ticker, name, highPrice, lowPrice, closingPrice, volume, 
                    fiftyTwoWeekHigh, fiftyTwoWeekLow, currentTime);
            PrintWriter writer = acontext.getResponse().getWriter();
            writer.write(msg);
            logger.log(Level.INFO, "Sent: {0}", msg);
            /* Close the connection
             * The client (JavaScript) makes a new one instantly */
            acontext.complete();
        } catch (IOException ex) {
            logger.log(Level.INFO, ex.toString());
        }
    }
}

/* Service method */
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {

    response.setContentType("text/html");

    /* Put request in async mode. */
    final AsyncContext acontext = request.startAsync();
    /* Remove from the queue when done */
    acontext.addListener(new AsyncListener() {
        @Override
        public void onComplete(AsyncEvent ae) throws IOException {
            requestQueue.remove(acontext);
            logger.log(Level.INFO, "Connection Being Closed.");
        }
        @Override
        public void onTimeout(AsyncEvent ae) throws IOException {
            requestQueue.remove(acontext);
            logger.log(Level.INFO, "Connection Has Timed Out.");
        }
        @Override
        public void onError(AsyncEvent ae) throws IOException {
            requestQueue.remove(acontext);
            logger.log(Level.INFO, "Connection error.");
        }
        @Override
        public void onStartAsync(AsyncEvent ae) throws IOException { }
    });
    /* Add to the queue */
    requestQueue.add(acontext);
    logger.log(Level.INFO, "Connection Being Opened.");
}

}

Class to get information from CSV

//Get Stock Data From CSV File
public static ArrayList<Stock> getListOfStocks() throws IOException {


    ArrayList<Stock> stocks = new ArrayList();
    ClassLoader classLoader = 
    Thread.currentThread().getContextClassLoader();
    InputStream is = 
    StockService.class.getResourceAsStream("/stockdata.csv");

    // create an instance of BufferedReader
    // using try with resource, Java 7 feature to close resources
    try (CSVReader reader = new CSVReader(new InputStreamReader(is))) {

        // read the first line from the text file
        String[] nextLine;
        reader.readNext();

        // loop until all lines are read
        while ((nextLine = reader.readNext()) != null) {

            Stock newStock = new Stock(nextLine[0], nextLine[1], 
                Float.valueOf(nextLine[2]), Float.valueOf(nextLine[3]),
                Float.valueOf(nextLine[4]), Integer.valueOf(nextLine[5]),
                Float.valueOf(nextLine[6]), Float.valueOf(nextLine[7]));

            stocks.add(newStock);
        }

    }

  return stocks;

}

Bean that retrieves and sends information

/* Updates price and volume information every second */
@Startup
@Singleton
public class PriceVolumeBean {
/* Use the container's timer service */
@Resource TimerService tservice;
private DukeETFServlet servlet;
//Set Variable for Counter
private int i = 0;
//Set date time variable

String currentTime;
//Set Variables for Stock Data
private String ticker;
private String name;
private float highPrice;
private float lowPrice;
private float closingPrice;
private int volume;
private float fiftyTwoWeekHigh;
private float fiftyTwoWeekLow;
private static final Logger logger = Logger.getLogger("PriceVolumeBean");

@PostConstruct
public void init() {
    /* Intialize the EJB and create a timer */
    logger.log(Level.INFO, "Initializing EJB.");
    servlet = null;
    tservice.createIntervalTimer(2000, 2000, new TimerConfig());
}

public void registerServlet(DukeETFServlet servlet) {
    /* Associate a servlet to send updates to */
    this.servlet = servlet;
}

@Timeout
public void timeout() throws IOException {

    // Update Date
    Date date = new Date();        

    // Set stock variables //
    ticker = StockService.getListOfStocks().get(i).getTicker();
    name = StockService.getListOfStocks().get(i).getName();
    highPrice = StockService.getListOfStocks().get(i).getHighPrice();
    lowPrice = StockService.getListOfStocks().get(i).getLowPrice();
    closingPrice = StockService.getListOfStocks().get(i).getClosingPrice();
    volume = StockService.getListOfStocks().get(i).getVolume();
    fiftyTwoWeekHigh = StockService.getListOfStocks().get(i).getFiftyTwoWeekHigh();
    fiftyTwoWeekLow = StockService.getListOfStocks().get(i).getFiftyTwoWeekLow();
    currentTime = date.toString();

    // Send updated information
    if (servlet != null)
        servlet.send(ticker, name, highPrice, lowPrice, closingPrice,
                volume, fiftyTwoWeekHigh, fiftyTwoWeekLow, currentTime);

    // Counter that keeps from going beyond size of arraylist
    i++;        
    if (i == 100) {
        i = 0;
    }

}
}

Working Screenshot Failing Screenshot Directory Structure

Community
  • 1
  • 1
Morgan
  • 87
  • 10
  • How are you building the WAR file? – Steve C May 05 '17 at 04:57
  • Netbeans builds it whenever I compile the program. I have checked the war for the file that I am trying to load and is it being compiled with it. – Morgan May 05 '17 at 04:58
  • How do you know that your `timeout` method is being invoked? (I just realised that your `getListOfStocks` method will NPE if it cannot read the `stockdata.csv` file) – Steve C May 05 '17 at 05:54
  • I'm going to go out on a limb here and say that when I run it through Netbeans, it works fine and ticks through each object in the ArrayList which would mean that my timeout method is working just fine. That's what the above screenshot showing data was supposed to imply. However, I do know that if it cannot read the stockdata.csv file, it will stop running the timeout method. – Morgan May 05 '17 at 06:18
  • To add on to that and give you some extra information, I also have a JSP within the application (for testing reasons) that can read the file just fine whether it is deployed by Netbeans or I do it manually. – Morgan May 05 '17 at 06:27
  • At this point I recommend starting Glassfish in debug mode (`asadmin start-domain --debug=true`) and remotely debug it from Netbeans. – Steve C May 05 '17 at 06:45
  • So I couldn't see anything wrong when running a debug so I ran glassfish in verbose mode and it is actually reading the file and sending the data but its just not showing up, nor throwing any errors. I have added the output to my post. – Morgan May 05 '17 at 07:37
  • What is `servlet` and how is it initialised? – Steve C May 05 '17 at 08:24
  • What do you mean? The servlet is what sends the information to my page. The servlet gets the information from a bean which gets the information from a separate class. It is setup using a timerservice and the main page uses an ajax request to request the information. I modified the duketf tutorial from the oracle javaee tutorials if you want to see and get a base idea of what I am talking about. – Morgan May 05 '17 at 08:34
  • But how does the class (stateless EJB?) with the timeout method get the reference to the servlet? – Steve C May 05 '17 at 08:50
  • I updated my post to include the whole servlet, the bean, and the class which gets the information from the CSV. Every 2 seconds the servlet toggles a connection to send a request to the bean which requests information from the class and sends it back to the servlet. – Morgan May 05 '17 at 09:58

0 Answers0