Runtime Exception

We are having an issue with getting this error after the sketch has run for a varied amount of time anywhere from 30mins to an 1hr 30mins.

I'm not sure if this is a coding issue or a hardware issue. We are running live capture blended with a recorded video. We are on a 2014 mac mini running through a fade candy. I'm not the one who wrote the code and have very limited grasp on it but our guy who did is out of town. I realize I haven't given any code but let me know if there are particular sections you would like to see that would help. I assume that posting the code in its entirety isn't the biggest help at the moment.

ava.lang.RuntimeException: java.lang.NullPointerException at com.jogamp.common.util.awt.AWTEDTExecutor.invoke(AWTEDTExecutor.java:58) at jogamp.opengl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:103) at jogamp.opengl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:206) at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:172) at javax.media.opengl.Threading.invoke(Threading.java:191) at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:541) at processing.opengl.PJOGL.requestDraw(PJOGL.java:688) at processing.opengl.PGraphicsOpenGL.requestDraw(PGraphicsOpenGL.java:1651) at processing.core.PApplet.run(PApplet.java:2256) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.NullPointerException at java.util.LinkedList.unlink(LinkedList.java:209) at java.util.LinkedList.remove(LinkedList.java:524) at processing.opengl.Texture.bufferUpdate(Texture.java:931) at processing.opengl.PGraphicsOpenGL.getTexture(PGraphicsOpenGL.java:6126) at processing.opengl.PGraphicsOpenGL$TexCache.getTexture(PGraphicsOpenGL.java:6918) at processing.opengl.PGraphicsOpenGL.flushPolys(PGraphicsOpenGL.java:2464) at processing.opengl.PGraphicsOpenGL.flush(PGraphicsOpenGL.java:2415) at processing.opengl.PGraphicsOpenGL.endDraw(PGraphicsOpenGL.java:1712) at STANLEY_live_flip_video.draw(STANLEY_live_flip_video.java:209) at processing.core.PApplet.handleDraw(PApplet.java:2386) at processing.opengl.PJOGL$PGLListener.display(PJOGL.java:862) at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:665) at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:649) at javax.media.opengl.awt.GLCanvas$10.run(GLCanvas.java:1289) at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1119) at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:994) at javax.media.opengl.awt.GLCanvas$11.run(GLCanvas.java:1300) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:302) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733) at java.awt.EventQueue.access$200(EventQueue.java:103) at java.awt.EventQueue$3.run(EventQueue.java:694) at java.awt.EventQueue$3.run(EventQueue.java:692) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:703) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Answers

  • Can you provide an MCVE that we can run? Without seeing your code, anything we say is just an uneducated guess.

  • Not a problem. the OPC class is code we got from fade candy I will make a second comment to post that code.

    import processing.video.*;

    String filename = "leaves_3d.m4v";

    float zoom = 2;

    OPC opc; PImage dot; Movie movie; Capture video; PGraphics[] pyramid;

    //------ start of setTileGrid parameters ------

    int tileCountX = 2; // two columns of tiles int tileCountY = 6; // six rows of tiles int tileLedsX = 4; int tileLedsY = 4; boolean zigzagRows = true; boolean bVideo = true;

    // tiles are rotated -90 degrees clockwise = first led on each tile is at bottom left float tileAngle = radians(0);

    // tileGrid is the visual-display order of the tiles. // This array must always contain (tileCountX * tileCountY) entries. // Numbers in this array are tile-numbers. // If there are 16 leds per tile, tile #1 is the tile holding the LEDs 0 thru 15. int tileGrid[] =
    { 12, 11, 9, 10, 8, 7, 5, 6, 4, 3, 1, 2 };

    //------ end of setTileGrid parameters ------

    // Set the location of several LEDs arranged in a grid. The first strip is // at 'angle', measured in radians clockwise from +X. // (x,y) is the center of the grid. void ledGridReverse(int index, int stripLength, int numStrips, float x, float y, float ledSpacing, float stripSpacing, float angle, boolean zigzag) { float s = sin(angle + HALF_PI); float c = cos(angle + HALF_PI); for (int i = 0; i < numStrips; i++) { opc.ledStrip(index + stripLength * i, stripLength, x - (i - (numStrips-1)/2.0) * stripSpacing * c, y - (i - (numStrips-1)/2.0) * stripSpacing * s, ledSpacing, angle, zigzag && (i % 2) == 1); } }

    // --- Initialize the grid for all tiles --- // NOTE1: This assumes the first led on each tile is the bottom left corner. // Change the value of tileAngle appropriately if this is not correct. // NOTE2: This assumes the tiles are square.

    void initTileGrid() { int totalTiles = tileCountX * tileCountY; int ledsPerTile = tileLedsX * tileLedsY; float tilePixelsX = width / ((tileCountX * tileLedsX) + 1); float tilePixelsY = height / ((tileCountY * tileLedsY) + 1); float pixelSpacing = min(tilePixelsX, tilePixelsY); // make the grid square float centerOfLeftTile = (width / 2) - (((tileCountX - 1) * pixelSpacing * tileLedsX) / 2); float centerOfTopTile = (height / 2) - (((tileCountY - 1) * pixelSpacing * tileLedsY) / 2); float centerX, centerY;

    println("pixelSpacing = ",pixelSpacing);

    // I know this looks a bit odd (having a for x loop inside a for y loop). // It's necessary to make the tileGrid array map correctly to the tile positions. int i = 0; centerY = centerOfTopTile; for (int y = 0; (y < tileCountY); ++y) { centerX = centerOfLeftTile; for (int x = 0; (x < tileCountX); ++x, ++i) { ledGridReverse((tileGrid[i] - 1) * ledsPerTile, tileLedsX, tileLedsY, centerX, centerY, pixelSpacing, pixelSpacing, tileAngle, zigzagRows);

      centerX += pixelSpacing * tileLedsX;
    }
    centerY += pixelSpacing * tileLedsY;
    

    } }

    //-----------------------------------------------------

    void setup() { if (bVideo) { frameRate(30); size(480, 240, P3D);

    // Connect to the local instance of fcserver. You can change this line to connect to another computer's fcserver
    opc = new OPC(this, "127.0.0.1", 7890);
    

    // Brian to move the dots out to edge of the video, reduce the number after width or height below.

    // opc.ledGrid(0, 32, 16, width/2, height/2, width / 30.0, height/ 16.0, 0, true); initTileGrid(); video = new Capture(this,480,240,30); video.start(); movie = new Movie(this, filename); movie.loop();

    pyramid = new PGraphics[4];
    for (int i = 0; i < pyramid.length; i++) {
      pyramid[i] = createGraphics(width / (1 << i), height / (1 << i), P3D);
    }
    

    } else { frameRate(30); // size(640, 360); size(480, 240, P3D);

    dot = loadImage("dot.png");
    
    // Connect to the local instance of fcserver. You can change this line to connect to another computer's fcserver
    opc = new OPC(this, "127.0.0.1", 7890);
    
    // map tiles in the pattern defined by the tileGrid array
    initTileGrid();
    

    }

    }

    void keyPressed() { if (key == 'd') opc.setDithering(false); if (key == ' ') movie.pause(); if (key == ']') zoom *= 1.1; if (key == '[') zoom *= 0.9; }

    void keyReleased() { if (key == 'd') opc.setDithering(true); if (key == ' ') movie.play(); }

    void movieEvent(Movie m) { m.read(); }

    void draw() { if (bVideo) { // Scale to width, center height int mWidth = int(pyramid[0].width * zoom); int mHeight = mWidth * movie.height / movie.width;

    // Center location
    float x, y;
    
    if (mousePressed) {
      // Pan horizontally and vertically with the mouse
      x = -mouseX * (mWidth - pyramid[0].width) / width;
      y = -mouseY * (mHeight - pyramid[0].height) / height;
    } else {
      // Centered
      x = -(mWidth - pyramid[0].width) / 2;
      y = -(mHeight - pyramid[0].height) / 2;
    }
    
    pyramid[0].beginDraw();
    pyramid[0].background(0);
    pyramid[0].tint(255, 255); // this adjusts opacity of recorded video
    pyramid[0].image(movie, x, y, mWidth, mHeight);
    pyramid[0].pushMatrix();
    pyramid[0].translate(width,0);
    pyramid[0].scale(-1,1);//mirror the video
    pyramid[0].tint(255, 150);
    pyramid[0].image(video, x, y, mWidth, mHeight);  
    pyramid[0].popMatrix();    //second number adjusts opacity from 0 to 255
    pyramid[0].endDraw();
    if (video.available()) {
      // If so, Step 4. Read the image from the camera.
      video.read();
    }
    for (int i = 1; i < pyramid.length; i++) {
      pyramid[i].beginDraw();
      pyramid[i].image(pyramid[i-1], 0, 0, pyramid[i].width, pyramid[i].height);
      pyramid[i].endDraw();
    }
    
    image(pyramid[pyramid.length - 1], 0, 0, width, height);
    

    } else {

    background(0);
    
    // Change the dot size as a function of time, to make it "throb"
    //float dotSize = height * 0.6 * (1.0 + 0.2 * sin(millis() * 0.01));
    
    //no throb 
    float dotSize = height * 0.6;
    
    // Draw it centered at the mouse location
    image(dot, mouseX - dotSize/2, mouseY - dotSize/2, dotSize, dotSize);
    

    } }

  • /* * Simple Open Pixel Control client for Processing, * designed to sample each LED's color from some point on the canvas. * * Micah Elizabeth Scott, 2013 * This file is released into the public domain. */

    import java.net.*; import java.util.Arrays;

    public class OPC { Socket socket; OutputStream output; String host; int port;

    int[] pixelLocations; byte[] packetData; byte firmwareConfig; String colorCorrection; boolean enableShowLocations;

    OPC(PApplet parent, String host, int port) { this.host = host; this.port = port; this.enableShowLocations = true; parent.registerDraw(this); }

    // Set the location of a single LED void led(int index, int x, int y)
    { // For convenience, automatically grow the pixelLocations array. We do want this to be an array, // instead of a HashMap, to keep draw() as fast as it can be. if (pixelLocations == null) { pixelLocations = new int[index + 1]; } else if (index >= pixelLocations.length) { pixelLocations = Arrays.copyOf(pixelLocations, index + 1); }

    pixelLocations[index] = x + width * y;
    

    }

    // Set the location of several LEDs arranged in a strip. // Angle is in radians, measured clockwise from +X. // (x,y) is the center of the strip. void ledStrip(int index, int count, float x, float y, float spacing, float angle, boolean reversed) { float s = sin(angle); float c = cos(angle); for (int i = 0; i < count; i++) { led(reversed ? (index + count - 1 - i) : (index + i), (int)(x + (i - (count-1)/2.0) * spacing * c + 0.5), (int)(y + (i - (count-1)/2.0) * spacing * s + 0.5)); } }

    // Set the locations of a ring of LEDs. The center of the ring is at (x, y), // with "radius" pixels between the center and each LED. The first LED is at // the indicated angle, in radians, measured clockwise from +X. void ledRing(int index, int count, float x, float y, float radius, float angle) { for (int i = 0; i < count; i++) { float a = angle + i * 2 * PI / count; led(index + i, (int)(x - radius * cos(a) + 0.5), (int)(y - radius * sin(a) + 0.5)); } }

    // Set the location of several LEDs arranged in a grid. The first strip is // at 'angle', measured in radians clockwise from +X. // (x,y) is the center of the grid. void ledGrid(int index, int stripLength, int numStrips, float x, float y, float ledSpacing, float stripSpacing, float angle, boolean zigzag) { float s = sin(angle + HALF_PI); float c = cos(angle + HALF_PI); for (int i = 0; i < numStrips; i++) { ledStrip(index + stripLength * i, stripLength, x + (i - (numStrips-1)/2.0) * stripSpacing * c, y + (i - (numStrips-1)/2.0) * stripSpacing * s, ledSpacing, angle, zigzag && (i % 2) == 1); } }

    // Set the location of 64 LEDs arranged in a uniform 8x8 grid. // (x,y) is the center of the grid. void ledGrid8x8(int index, float x, float y, float spacing, float angle, boolean zigzag) { ledGrid(index, 8, 8, x, y, spacing, spacing, angle, zigzag); }

    // Should the pixel sampling locations be visible? This helps with debugging. // Showing locations is enabled by default. You might need to disable it if our drawing // is interfering with your processing sketch, or if you'd simply like the screen to be // less cluttered. void showLocations(boolean enabled) { enableShowLocations = enabled; }

    // Enable or disable dithering. Dithering avoids the "stair-stepping" artifact and increases color // resolution by quickly jittering between adjacent 8-bit brightness levels about 400 times a second. // Dithering is on by default. void setDithering(boolean enabled) { if (enabled) firmwareConfig &= ~0x01; else firmwareConfig |= 0x01; sendFirmwareConfigPacket(); }

    // Enable or disable frame interpolation. Interpolation automatically blends between consecutive frames // in hardware, and it does so with 16-bit per channel resolution. Combined with dithering, this helps make // fades very smooth. Interpolation is on by default. void setInterpolation(boolean enabled) { if (enabled) firmwareConfig &= ~0x02; else firmwareConfig |= 0x02; sendFirmwareConfigPacket(); }

    // Put the Fadecandy onboard LED under automatic control. It blinks any time the firmware processes a packet. // This is the default configuration for the LED. void statusLedAuto() { firmwareConfig &= 0x0C; sendFirmwareConfigPacket(); }

    // Manually turn the Fadecandy onboard LED on or off. This disables automatic LED control. void setStatusLed(boolean on) { firmwareConfig |= 0x04; // Manual LED control if (on) firmwareConfig |= 0x08; else firmwareConfig &= ~0x08; sendFirmwareConfigPacket(); }

    // Set the color correction parameters void setColorCorrection(float gamma, float red, float green, float blue) { colorCorrection = "{ \"gamma\": " + gamma + ", \"whitepoint\": [" + red + "," + green + "," + blue + "]}"; sendColorCorrectionPacket(); }

    // Set custom color correction parameters from a string void setColorCorrection(String s) { colorCorrection = s; sendColorCorrectionPacket(); }

    // Send a packet with the current firmware configuration settings void sendFirmwareConfigPacket() { if (output == null) { // We'll do this when we reconnect return; }

    byte[] packet = new byte[9];
    packet[0] = 0;          // Channel (reserved)
    packet[1] = (byte)0xFF; // Command (System Exclusive)
    packet[2] = 0;          // Length high byte
    packet[3] = 5;          // Length low byte
    packet[4] = 0x00;       // System ID high byte
    packet[5] = 0x01;       // System ID low byte
    packet[6] = 0x00;       // Command ID high byte
    packet[7] = 0x02;       // Command ID low byte
    packet[8] = firmwareConfig;
    
    try {
      output.write(packet);
    } catch (Exception e) {
      dispose();
    }
    

    }

    // Send a packet with the current color correction settings void sendColorCorrectionPacket() { if (colorCorrection == null) { // No color correction defined return; } if (output == null) { // We'll do this when we reconnect return; }

    byte[] content = colorCorrection.getBytes();
    int packetLen = content.length + 4;
    byte[] header = new byte[8];
    header[0] = 0;          // Channel (reserved)
    header[1] = (byte)0xFF; // Command (System Exclusive)
    header[2] = (byte)(packetLen >> 8);
    header[3] = (byte)(packetLen & 0xFF);
    header[4] = 0x00;       // System ID high byte
    header[5] = 0x01;       // System ID low byte
    header[6] = 0x00;       // Command ID high byte
    header[7] = 0x01;       // Command ID low byte
    
    try {
      output.write(header);
      output.write(content);
    } catch (Exception e) {
      dispose();
    }
    

    }

    // Automatically called at the end of each draw(). // This handles the automatic Pixel to LED mapping. // If you aren't using that mapping, this function has no effect. // In that case, you can call setPixelCount(), setPixel(), and writePixels() // separately. void draw() { if (pixelLocations == null) { // No pixels defined yet return; }

    if (output == null) {
      // Try to (re)connect
      connect();
    }
    if (output == null) {
      return;
    }
    
    int numPixels = pixelLocations.length;
    int ledAddress = 4;
    
    setPixelCount(numPixels);
    loadPixels();
    
    for (int i = 0; i < numPixels; i++) {
      int pixelLocation = pixelLocations[i];
      int pixel = pixels[pixelLocation];
    
      packetData[ledAddress] = (byte)(pixel >> 16);
      packetData[ledAddress + 1] = (byte)(pixel >> 8);
      packetData[ledAddress + 2] = (byte)pixel;
      ledAddress += 3;
    
      if (enableShowLocations) {
        pixels[pixelLocation] = 0xFFFFFF ^ pixel;
      }
    }
    
    writePixels();
    
    if (enableShowLocations) {
      updatePixels();
    }
    

    }

    // Change the number of pixels in our output packet. // This is normally not needed; the output packet is automatically sized // by draw() and by setPixel(). void setPixelCount(int numPixels) { int numBytes = 3 * numPixels; int packetLen = 4 + numBytes; if (packetData == null || packetData.length != packetLen) { // Set up our packet buffer packetData = new byte[packetLen]; packetData[0] = 0; // Channel packetData[1] = 0; // Command (Set pixel colors) packetData[2] = (byte)(numBytes >> 8); packetData[3] = (byte)(numBytes & 0xFF); } }

    // Directly manipulate a pixel in the output buffer. This isn't needed // for pixels that are mapped to the screen. void setPixel(int number, color c) { int offset = 4 + number * 3; if (packetData == null || packetData.length < offset + 3) { setPixelCount(number + 1); }

    packetData[offset] = (byte) (c >> 16);
    packetData[offset + 1] = (byte) (c >> 8);
    packetData[offset + 2] = (byte) c;
    

    }

    // Read a pixel from the output buffer. If the pixel was mapped to the display, // this returns the value we captured on the previous frame. color getPixel(int number) { int offset = 4 + number * 3; if (packetData == null || packetData.length < offset + 3) { return 0; } return (packetData[offset] << 16) | (packetData[offset + 1] << 8) | packetData[offset + 2]; }

    // Transmit our current buffer of pixel values to the OPC server. This is handled // automatically in draw() if any pixels are mapped to the screen, but if you haven't // mapped any pixels to the screen you'll want to call this directly. void writePixels() { if (packetData == null || packetData.length == 0) { // No pixel buffer return; } if (output == null) { // Try to (re)connect connect(); } if (output == null) { return; }

    try {
      output.write(packetData);
    } catch (Exception e) {
      dispose();
    }
    

    }

    void dispose() { // Destroy the socket. Called internally when we've disconnected. if (output != null) { println("Disconnected from OPC server"); } socket = null; output = null; }

    void connect() { // Try to connect to the OPC server. This normally happens automatically in draw() try { socket = new Socket(host, port); socket.setTcpNoDelay(true); output = socket.getOutputStream(); println("Connected to OPC server"); } catch (ConnectException e) { dispose(); } catch (IOException e) { dispose(); }

    sendColorCorrectionPacket();
    sendFirmwareConfigPacket();
    

    } }

  • Yikes, that's a ton of unformatted code. You'll probably have much better luck if you try to minimize that code- that's what the first M of MCVE stands for. Try to eliminate any code that isn't directly related to the exception- half the time, you'll figure it out in the process of creating an MCVE!

    Also, please use the code button when posting code. Just highlight your code and press the code button to preserve your formatting in your post.

  • oh gosh that might be out of my skill set. I appreciate the responses though. I will see if I can't pair it down but I don't know that I understand the code well enough to remove and rebuild things. This was kind of a last ditch effort since the guy who's been handling the code is out of pocket and we need a fix soon. Again I really appreciate the help!

  • Generally, you wouldn't remove stuff. You'd start from scratch and only add stuff that directly relates to your error. Check out the MCVE link I posted for more info on how to create one.

Sign In or Register to comment.