/**
   * Gracefully terminate the active use of the public methods of this component. This method should
   * be the last one called on a given instance of this component.
   *
   * @exception LifecycleException if this component detects a fatal error that needs to be reported
   */
  public void stop() throws LifecycleException {

    if (debug >= 1) log("Stopping");

    // Validate and update our current component state
    if (!started) throw new LifecycleException(sm.getString("standardManager.notStarted"));
    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
    started = false;

    // Stop the background reaper thread
    threadStop();

    // Write out sessions
    try {
      unload();
    } catch (IOException e) {
      log(sm.getString("standardManager.managerUnload"), e);
    }

    // Expire all active sessions
    Session sessions[] = findSessions();
    for (int i = 0; i < sessions.length; i++) {
      StandardSession session = (StandardSession) sessions[i];
      if (!session.isValid()) continue;
      try {
        session.expire();
      } catch (Throwable t) {;
      }
    }

    // Require a new random number generator if we are restarted
    this.random = null;
  }
  /**
   * Load and return the Session associated with the specified session identifier from this Store,
   * without removing it. If there is no such stored Session, return <code>null</code>.
   *
   * @param id Session identifier of the session to load
   * @exception ClassNotFoundException if a deserialization error occurs
   * @exception IOException if an input/output error occurs
   */
  @Override
  public Session load(String id) throws ClassNotFoundException, IOException {

    // Open an input stream to the specified pathname, if any
    File file = file(id);
    if (file == null) {
      return (null);
    }

    if (!file.exists()) {
      return (null);
    }
    if (manager.getContext().getLogger().isDebugEnabled()) {
      manager
          .getContext()
          .getLogger()
          .debug(sm.getString(getStoreName() + ".loading", id, file.getAbsolutePath()));
    }

    ObjectInputStream ois = null;
    Loader loader = null;
    ClassLoader classLoader = null;
    ClassLoader oldThreadContextCL = Thread.currentThread().getContextClassLoader();
    try (FileInputStream fis = new FileInputStream(file.getAbsolutePath());
        BufferedInputStream bis = new BufferedInputStream(fis)) {
      Context context = manager.getContext();
      if (context != null) loader = context.getLoader();
      if (loader != null) classLoader = loader.getClassLoader();
      if (classLoader != null) {
        Thread.currentThread().setContextClassLoader(classLoader);
        ois = new CustomObjectInputStream(bis, classLoader);
      } else {
        ois = new ObjectInputStream(bis);
      }

      StandardSession session = (StandardSession) manager.createEmptySession();
      session.readObjectData(ois);
      session.setManager(manager);
      return (session);
    } catch (FileNotFoundException e) {
      if (manager.getContext().getLogger().isDebugEnabled())
        manager.getContext().getLogger().debug("No persisted data file found");
      return (null);
    } finally {
      if (ois != null) {
        // Close the input stream
        try {
          ois.close();
        } catch (IOException f) {
          // Ignore
        }
      }
      Thread.currentThread().setContextClassLoader(oldThreadContextCL);
    }
  }
Example #3
0
  /**
   * Called by our background reaper thread to check if Sessions saved in our store are subject of
   * being expired. If so expire the Session and remove it from the Store.
   */
  public void processExpires() {
    long timeNow = System.currentTimeMillis();
    String[] keys = null;

    if (!started) {
      return;
    }

    try {
      keys = keys();
    } catch (IOException e) {
      manager.getContainer().getLogger().error("Error getting keys", e);
      return;
    }
    if (manager.getContainer().getLogger().isDebugEnabled()) {
      manager
          .getContainer()
          .getLogger()
          .debug(getStoreName() + ": processExpires check number of " + keys.length + " sessions");
    }

    for (int i = 0; i < keys.length; i++) {
      try {
        StandardSession session = (StandardSession) load(keys[i]);
        if (session == null) {
          continue;
        }
        int timeIdle = (int) ((timeNow - session.thisAccessedTime) / 1000L);
        if (timeIdle < session.getMaxInactiveInterval()) {
          continue;
        }
        if (manager.getContainer().getLogger().isDebugEnabled()) {
          manager
              .getContainer()
              .getLogger()
              .debug(getStoreName() + ": processExpires expire store session " + keys[i]);
        }
        if (((PersistentManagerBase) manager).isLoaded(keys[i])) {
          // recycle old backup session
          session.recycle();
        } else {
          // expire swapped out session
          session.expire();
        }
        remove(keys[i]);
      } catch (Exception e) {
        manager.getContainer().getLogger().error("Session: " + keys[i] + "; ", e);
        try {
          remove(keys[i]);
        } catch (IOException e2) {
          manager.getContainer().getLogger().error("Error removing key", e2);
        }
      }
    }
  }
  /** Invalidate all sessions that have expired. */
  private void processExpires() {

    long timeNow = System.currentTimeMillis();
    Session sessions[] = findSessions();

    for (int i = 0; i < sessions.length; i++) {
      StandardSession session = (StandardSession) sessions[i];
      if (!session.isValid()) continue;
      int maxInactiveInterval = session.getMaxInactiveInterval();
      if (maxInactiveInterval < 0) continue;
      int timeIdle = // Truncate, do not round up
          (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
      if (timeIdle >= maxInactiveInterval) {
        try {
          session.expire();
        } catch (Throwable t) {
          log(sm.getString("standardManager.expireException"), t);
        }
      }
    }
  }
  /**
   * Save the specified Session into this Store. Any previously saved information for the associated
   * session identifier is replaced.
   *
   * @param session Session to be saved
   * @exception IOException if an input/output error occurs
   */
  @Override
  public void save(Session session) throws IOException {

    // Open an output stream to the specified pathname, if any
    File file = file(session.getIdInternal());
    if (file == null) {
      return;
    }
    if (manager.getContext().getLogger().isDebugEnabled()) {
      manager
          .getContext()
          .getLogger()
          .debug(
              sm.getString(
                  getStoreName() + ".saving", session.getIdInternal(), file.getAbsolutePath()));
    }

    try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath());
        ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) {
      ((StandardSession) session).writeObjectData(oos);
    }
  }
  /**
   * Save any currently active sessions in the appropriate persistence mechanism, if any. If
   * persistence is not supported, this method returns without doing anything.
   *
   * @exception IOException if an input/output error occurs
   */
  public void unload() throws IOException {

    if (debug >= 1) log("Unloading persisted sessions");

    // Open an output stream to the specified pathname, if any
    File file = file();
    if (file == null) return;
    if (debug >= 1) log(sm.getString("standardManager.unloading", pathname));
    FileOutputStream fos = null;
    ObjectOutputStream oos = null;
    try {
      fos = new FileOutputStream(file.getAbsolutePath());
      oos = new ObjectOutputStream(new BufferedOutputStream(fos));
    } catch (IOException e) {
      log(sm.getString("standardManager.unloading.ioe", e), e);
      if (oos != null) {
        try {
          oos.close();
        } catch (IOException f) {;
        }
        oos = null;
      }
      throw e;
    }

    // Write the number of active sessions, followed by the details
    ArrayList list = new ArrayList();
    synchronized (sessions) {
      if (debug >= 1) log("Unloading " + sessions.size() + " sessions");
      try {
        oos.writeObject(new Integer(sessions.size()));
        Iterator elements = sessions.values().iterator();
        while (elements.hasNext()) {
          StandardSession session = (StandardSession) elements.next();
          list.add(session);
          session.passivate();
          session.writeObjectData(oos);
        }
      } catch (IOException e) {
        log(sm.getString("standardManager.unloading.ioe", e), e);
        if (oos != null) {
          try {
            oos.close();
          } catch (IOException f) {;
          }
          oos = null;
        }
        throw e;
      }
    }

    // Flush and close the output stream
    try {
      oos.flush();
      oos.close();
      oos = null;
    } catch (IOException e) {
      if (oos != null) {
        try {
          oos.close();
        } catch (IOException f) {;
        }
        oos = null;
      }
      throw e;
    }

    // Expire all the sessions we just wrote
    if (debug >= 1) log("Expiring " + list.size() + " persisted sessions");
    Iterator expires = list.iterator();
    while (expires.hasNext()) {
      StandardSession session = (StandardSession) expires.next();
      try {
        session.expire(false);
      } catch (Throwable t) {;
      }
    }

    if (debug >= 1) log("Unloading complete");
  }
  /**
   * Load any currently active sessions that were previously unloaded to the appropriate persistence
   * mechanism, if any. If persistence is not supported, this method returns without doing anything.
   *
   * @exception ClassNotFoundException if a serialized class cannot be found during the reload
   * @exception IOException if an input/output error occurs
   */
  public void load() throws ClassNotFoundException, IOException {

    if (debug >= 1) log("Start: Loading persisted sessions");

    // Initialize our internal data structures
    recycled.clear();
    sessions.clear();

    // Open an input stream to the specified pathname, if any
    File file = file();
    if (file == null) return;
    if (debug >= 1) log(sm.getString("standardManager.loading", pathname));
    FileInputStream fis = null;
    ObjectInputStream ois = null;
    Loader loader = null;
    ClassLoader classLoader = null;
    try {
      fis = new FileInputStream(file.getAbsolutePath());
      BufferedInputStream bis = new BufferedInputStream(fis);
      if (container != null) loader = container.getLoader();
      if (loader != null) classLoader = loader.getClassLoader();
      if (classLoader != null) {
        if (debug >= 1) log("Creating custom object input stream for class loader " + classLoader);
        ois = new CustomObjectInputStream(bis, classLoader);
      } else {
        if (debug >= 1) log("Creating standard object input stream");
        ois = new ObjectInputStream(bis);
      }
    } catch (FileNotFoundException e) {
      if (debug >= 1) log("No persisted data file found");
      return;
    } catch (IOException e) {
      log(sm.getString("standardManager.loading.ioe", e), e);
      if (ois != null) {
        try {
          ois.close();
        } catch (IOException f) {;
        }
        ois = null;
      }
      throw e;
    }

    // Load the previously unloaded active sessions
    synchronized (sessions) {
      try {
        Integer count = (Integer) ois.readObject();
        int n = count.intValue();
        if (debug >= 1) log("Loading " + n + " persisted sessions");
        for (int i = 0; i < n; i++) {
          StandardSession session = new StandardSession(this);
          session.readObjectData(ois);
          session.setManager(this);
          sessions.put(session.getId(), session);
          session.activate();
        }
      } catch (ClassNotFoundException e) {
        log(sm.getString("standardManager.loading.cnfe", e), e);
        if (ois != null) {
          try {
            ois.close();
          } catch (IOException f) {;
          }
          ois = null;
        }
        throw e;
      } catch (IOException e) {
        log(sm.getString("standardManager.loading.ioe", e), e);
        if (ois != null) {
          try {
            ois.close();
          } catch (IOException f) {;
          }
          ois = null;
        }
        throw e;
      } finally {
        // Close the input stream
        try {
          if (ois != null) ois.close();
        } catch (IOException f) {
          // ignored
        }

        // Delete the persistent storage file
        if (file != null && file.exists()) file.delete();
      }
    }

    if (debug >= 1) log("Finish: Loading persisted sessions");
  }
Example #8
0
  /**
   * Save a session to the Store.
   *
   * @param session the session to be stored
   * @exception IOException if an input/output error occurs
   */
  public void save(Session session) throws IOException {
    String saveSql =
        "INSERT INTO "
            + sessionTable
            + " ("
            + sessionIdCol
            + ", "
            + sessionAppCol
            + ", "
            + sessionDataCol
            + ", "
            + sessionValidCol
            + ", "
            + sessionMaxInactiveCol
            + ", "
            + sessionLastAccessedCol
            + ") VALUES (?, ?, ?, ?, ?, ?)";
    ObjectOutputStream oos = null;
    ByteArrayOutputStream bos = null;
    ByteArrayInputStream bis = null;
    InputStream in = null;

    synchronized (this) {
      Connection _conn = getConnection();
      if (_conn == null) {
        return;
      }

      // If sessions already exist in DB, remove and insert again.
      // TODO:
      // * Check if ID exists in database and if so use UPDATE.
      remove(session.getId());

      try {
        bos = new ByteArrayOutputStream();
        oos = new ObjectOutputStream(new BufferedOutputStream(bos));

        ((StandardSession) session).writeObjectData(oos);
        oos.close();

        byte[] obs = bos.toByteArray();
        int size = obs.length;
        bis = new ByteArrayInputStream(obs, 0, size);
        in = new BufferedInputStream(bis, size);

        if (preparedSaveSql == null) {
          preparedSaveSql = _conn.prepareStatement(saveSql);
        }

        preparedSaveSql.setString(1, session.getId());
        preparedSaveSql.setString(2, getName());
        preparedSaveSql.setBinaryStream(3, in, size);
        preparedSaveSql.setString(4, session.isValid() ? "1" : "0");
        preparedSaveSql.setInt(5, session.getMaxInactiveInterval());
        preparedSaveSql.setLong(6, session.getLastAccessedTime());
        preparedSaveSql.execute();
      } catch (SQLException e) {
        log(sm.getString(getStoreName() + ".SQLException", e));
      } catch (IOException e) {;
      } finally {
        if (bis != null) {
          bis.close();
        }
        if (in != null) {
          in.close();
        }

        release(_conn);
      }
    }

    if (debug > 0) {
      log(sm.getString(getStoreName() + ".saving", session.getId(), sessionTable));
    }
  }
Example #9
0
  /**
   * Load the Session associated with the id <code>id</code>. If no such session is found <code>null
   * </code> is returned.
   *
   * @param id a value of type <code>String</code>
   * @return the stored <code>Session</code>
   * @exception ClassNotFoundException if an error occurs
   * @exception IOException if an input/output error occurred
   */
  public Session load(String id) throws ClassNotFoundException, IOException {
    ResultSet rst = null;
    StandardSession _session = null;
    Loader loader = null;
    ClassLoader classLoader = null;
    ObjectInputStream ois = null;
    BufferedInputStream bis = null;
    Container container = manager.getContainer();
    String loadSql =
        "SELECT "
            + sessionIdCol
            + ", "
            + sessionDataCol
            + " FROM "
            + sessionTable
            + " WHERE "
            + sessionIdCol
            + " = ? AND "
            + sessionAppCol
            + " = ?";

    synchronized (this) {
      Connection _conn = getConnection();
      if (_conn == null) {
        return (null);
      }

      try {
        if (preparedLoadSql == null) {
          preparedLoadSql = _conn.prepareStatement(loadSql);
        }

        preparedLoadSql.setString(1, id);
        preparedLoadSql.setString(2, getName());
        rst = preparedLoadSql.executeQuery();
        if (rst.next()) {
          bis = new BufferedInputStream(rst.getBinaryStream(2));

          if (container != null) {
            loader = container.getLoader();
          }
          if (loader != null) {
            classLoader = loader.getClassLoader();
          }
          if (classLoader != null) {
            ois = new CustomObjectInputStream(bis, classLoader);
          } else {
            ois = new ObjectInputStream(bis);
          }

          if (debug > 0) {
            log(sm.getString(getStoreName() + ".loading", id, sessionTable));
          }

          _session = (StandardSession) manager.createEmptySession();
          _session.readObjectData(ois);
          _session.setManager(manager);

        } else if (debug > 0) {
          log(getStoreName() + ": No persisted data object found");
        }
      } catch (SQLException e) {
        log(sm.getString(getStoreName() + ".SQLException", e));
      } finally {
        try {
          if (rst != null) {
            rst.close();
          }
        } catch (SQLException e) {;
        }
        if (ois != null) {
          try {
            ois.close();
          } catch (IOException e) {;
          }
        }
        release(_conn);
      }
    }

    return (_session);
  }