问:
Bad lighting using Phong Method
I'm trying to make a cube, which is irregularly triangulated, but virtually coplanar, shade correctly.

Here is the current result I have:

With wireframe:

Normals calculated in my program:

Normals calculated by meshlabjs.net:

The lighting works properly when using regular size triangles for the cube. As you can see, I'm duplicating vertices and using angle weighting.

lighting.frag

```<code>vec4 scene_ambient = vec4(1, 1, 1, 1.0);

struct material
{
  vec4 ambient;
  vec4 diffuse;
  vec4 specular;
  float shininess;
};

material frontMaterial = material(
  vec4(0.25, 0.25, 0.25, 1.0),
  vec4(0.4, 0.4, 0.4, 1.0),
  vec4(0.774597, 0.774597, 0.774597, 1.0),
  76
);

struct lightSource
{
  vec4 position;
  vec4 diffuse;
  vec4 specular;
  float constantAttenuation, linearAttenuation, quadraticAttenuation;
  float spotCutoff, spotExponent;
  vec3 spotDirection;
};

lightSource light0 = lightSource(
  vec4(0.0,  0.0, 0.0, 1.0),
  vec4(100.0,  100.0,  100.0, 100.0),
  vec4(100.0,  100.0,  100.0, 100.0),
  0.1, 1, 0.01,
  180.0, 0.0,
  vec3(0.0, 0.0, 0.0)
);

vec4 light(lightSource ls, vec3 norm, vec3 deviation, vec3 position)
{
  vec3 viewDirection = normalize(vec3(1.0 * vec4(0, 0, 0, 1.0) - vec4(position, 1)));

  vec3 lightDirection;
  float attenuation;

  //ls.position.xyz = cameraPos;
  ls.position.z += 50;

  if (0.0 == ls.position.w) // directional light?
  {
    attenuation = 1.0; // no attenuation
    lightDirection = normalize(vec3(ls.position));
  }
  else // point light or spotlight (or other kind of light)
  {
      vec3 positionToLightSource = vec3(ls.position - vec4(position, 1.0));
    float distance = length(positionToLightSource);
    lightDirection = normalize(positionToLightSource);
    attenuation = 1.0 / (ls.constantAttenuation
      + ls.linearAttenuation * distance
      + ls.quadraticAttenuation * distance * distance);

    if (ls.spotCutoff <= 90.0) // spotlight?
    {
      float clampedCosine = max(0.0, dot(-lightDirection, ls.spotDirection));
      if (clampedCosine < cos(radians(ls.spotCutoff))) // outside of spotlight cone?
      {
        attenuation = 0.0;
        }
      else
        {
        attenuation = attenuation * pow(clampedCosine, ls.spotExponent);
        }
    }
  }

  vec3 ambientLighting = vec3(scene_ambient) * vec3(frontMaterial.ambient);

  vec3 diffuseReflection = attenuation
    * vec3(ls.diffuse) * vec3(frontMaterial.diffuse)
    * max(0.0, dot(norm, lightDirection));

  vec3 specularReflection;
  if (dot(norm, lightDirection) < 0.0) // light source on the wrong side?
  {
    specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
  }
  else // light source on the right side
  {
    specularReflection = attenuation * vec3(ls.specular) * vec3(frontMaterial.specular)
         * pow(max(0.0, dot(reflect(lightDirection, norm), viewDirection)), frontMaterial.shininess);
  }

  return vec4(ambientLighting + diffuseReflection + specularReflection, 1.0);
}

vec4 generateGlobalLighting(vec3 norm, vec3 position)
{
  return light(light0, norm, vec3(2,0,0), position);
}
</code>```

mainmesh.frag

```<code>#version 430
in vec3 f_color;
in vec3 f_normal;
in vec3 f_position;

in float f_opacity;

out vec4 fragColor;

vec4 generateGlobalLighting(vec3 norm, vec3 position);

void main()
{
  vec3 norm = normalize(f_normal);
  vec4 l0 = generateGlobalLighting(norm, f_position);

  fragColor = vec4(f_color, f_opacity) * l0;
}
</code>```

Follows the code to generate the verts, normals and faces for the painter.

```<code>m_vertices_buf.resize(m_mesh.num_faces() * 3, 3);
m_normals_buf.resize(m_mesh.num_faces() * 3, 3);
m_faces_buf.resize(m_mesh.num_faces(), 3);

std::map<vertex_descriptor, std::list<Vector3d>> map;
GLDebugging* deb = GLDebugging::getInstance();

auto getAngle = [](Vector3d a, Vector3d b) {
    double angle = 0.0;
    angle = std::atan2(a.cross(b).norm(), a.dot(b));
    return angle;
};

for (const auto& f : m_mesh.faces()) {
    auto f_hh = m_mesh.halfedge(f);
    //auto n = PMP::compute_face_normal(f, m_mesh);

    vertex_descriptor vs[3];
    Vector3d ps[3];

    int i = 0;
    for (const auto& v : m_mesh.vertices_around_face(f_hh)) {
        auto p = m_mesh.point(v);
        ps[i] = Vector3d(p.x(), p.y(), p.z());
        vs[i++] = v;
    }

    auto n = (ps[1] - ps[0]).cross(ps[2] - ps[0]).normalized();

    auto a1 = getAngle((ps[1] - ps[0]).normalized(), (ps[2] - ps[0]).normalized());
    auto a2 = getAngle((ps[2] - ps[1]).normalized(), (ps[0] - ps[1]).normalized());
    auto a3 = getAngle((ps[0] - ps[2]).normalized(), (ps[1] - ps[2]).normalized());

    auto area = PMP::face_area(f, m_mesh);

    map[vs[0]].push_back(n * a1);
    map[vs[1]].push_back(n * a2);
    map[vs[2]].push_back(n * a3);

    auto p = m_mesh.point(vs[0]);
    deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);

    p = m_mesh.point(vs[1]);
    deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);

    p = m_mesh.point(vs[2]);
    deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);
}

int j = 0;
int i = 0;
for (const auto& f : m_mesh.faces()) {
    auto f_hh = m_mesh.halfedge(f);
    for (const auto& v : m_mesh.vertices_around_face(f_hh)) {
        const auto& p = m_mesh.point(v);
        m_vertices_buf.row(i) = RowVector3d(p.x(), p.y(), p.z());

        Vector3d n(0, 0, 0);

        //auto n = PMP::compute_face_normal(f, m_mesh);
        Vector3d norm = Vector3d(n.x(), n.y(), n.z());

        for (auto val : map[v]) {
            norm += val;
        }

        norm.normalize();

        deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(norm.x(), norm.y(), norm.z()) * 3,
            Vector3d(1.0, 0, 0));

        m_normals_buf.row(i++) = RowVector3d(norm.x(), norm.y(), norm.z());
    }

    m_faces_buf.row(j++) = RowVector3i(i - 3, i - 2, i - 1);
}
</code>```

Follows the painter code:

```<code>m_vertexAttrLoc = program.attributeLocation("v_vertex");
m_colorAttrLoc = program.attributeLocation("v_color");
m_normalAttrLoc = program.attributeLocation("v_normal");

m_mvMatrixLoc = program.uniformLocation("v_modelViewMatrix");
m_projMatrixLoc = program.uniformLocation("v_projectionMatrix");
m_normalMatrixLoc = program.uniformLocation("v_normalMatrix");
//m_relativePosLoc = program.uniformLocation("v_relativePos");
m_opacityLoc = program.uniformLocation("v_opacity");
m_colorMaskLoc = program.uniformLocation("v_colorMask");

//bool for unmapping depth color
m_useDepthMap = program.uniformLocation("v_useDepthMap");
program.setUniformValue(m_mvMatrixLoc, modelView);

//uniform used for Color map to regular model switch
program.setUniformValue(m_useDepthMap, (m_showColorMap &&
    (m_showProblemAreas || m_showPrepMap || m_showDepthMap || m_showMockupMap)));

QMatrix3x3 normalMatrix = modelView.normalMatrix();
program.setUniformValue(m_normalMatrixLoc, normalMatrix);
program.setUniformValue(m_projMatrixLoc, projection);

//program.setUniformValue(m_relativePosLoc, m_relativePos);
program.setUniformValue(m_opacityLoc, m_opacity);
program.setUniformValue(m_colorMaskLoc, m_colorMask);

glEnableVertexAttribArray(m_vertexAttrLoc);
m_vertices.bind();
glVertexAttribPointer(m_vertexAttrLoc, 3, GL_DOUBLE, false, 3 * sizeof(GLdouble), NULL);
m_vertices.release();

glEnableVertexAttribArray(m_normalAttrLoc);
m_normals.bind();
glVertexAttribPointer(m_normalAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
m_normals.release();

glEnableVertexAttribArray(m_colorAttrLoc);

if (m_showProblemAreas) {
    m_problemColorMap.bind();
    glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    m_problemColorMap.release();
}
else if (m_showPrepMap) {
    m_prepColorMap.bind();
    glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    m_prepColorMap.release();
}
else if (m_showMockupMap) {
    m_mokupColorMap.bind();
    glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    m_mokupColorMap.release();
}
else {
    //m_colors.bind();
    //glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    //m_colors.release();
}

m_indices.bind();
glDrawElements(GL_TRIANGLES, m_indices.size() / sizeof(int), GL_UNSIGNED_INT, NULL);
m_indices.release();

glDisableVertexAttribArray(m_vertexAttrLoc);
glDisableVertexAttribArray(m_normalAttrLoc);
glDisableVertexAttribArray(m_colorAttrLoc);
</code>```

EDIT: Sorry for not being clear enough. The cube is merely an example. My requirements are that the shading works for any kind of mesh. Those with very sharp edges, and those that are very organic (like humans or animals).

答:
The issue is clearly explained by the image "Normals calculated in my program" from your question. The normal vectors at the corners and edges of the cube are not normal perpendicular to the faces:

For a proper specular reflection on plane faces, the normal vectors have to be perpendicular to the sides of the cube.

The vertex coordinate and its normal vector from a tuple with 6 components (x, y, z, nx, ny, nz).
A vertex coordinate on an edge of the cube is adjacent to 2 sides of the cube and 2 (face) normal vectors. The 8 vertex coordinates on the 8 corners of the cube are adjacent to 3 sides (3 normal vectors) each.

To define the vertex attributes with face normal vectors (perpendicular to a side) you have to define multiple tuples with the same vertex coordinate but different normal vectors. You have to use the different attribute tuples to form the triangle primitives on the different sides of the cube.

e.g. If you have defined a cube with the left, front, bottom coordinate of (-1, -1, -1) and the right, back, top coordinate of (1, 1, 1), then the vertex coordinate (-1, -1, -1) is adjacent to the left, front and bottom side of the cube:

         x  y  z   nx ny nz
left:   -1 -1 -1   -1  0  0
front:  -1 -1 -1    0 -1  0
bottom: -1 -1 -1    0  0 -1
```

Use the left attribute tuple to form the triangle primitives on the left side, the front to form the front and bottom for the triangles on the bottom.

In general you have to decide what you want. There is no general approach for all meshes.

Either you have a fine granulated mesh and you want a smooth appearance (e.g a sphere). In that case your approach is fine, it will generate a smooth light transition on the edges between the primitives.

Or you have a mesh with hard edges like a cube. In that case you have to "duplicate" vertices. If 2 (or even more) triangles share a vertex coordinate, but the face normal vectors are different, then you have to create a separate tuple, for all the combinations of the vertex coordinate and the face normal vector.

For a general "smooth" solution you would have to interpolate the normal vectors of the vertex coordinates which are in the middle of plane surfaces, according to the surrounding geometry. That means if a bunch of triangle primitives form a plane, then all the normal vectors of the vertices have to be computed dependent on there position on the plane. At the centroid the normal vector is equal to the face normal vector. For all other points the normal vector has to be interpolated with the normal vectors of the surrounding faces.

Anyway that seems to be an XY problem. Why is there a "vertex" somewhere in the middle of a plane? Probably the plane is tessellated. But if the plan is tessellated, why are the normal vectors not interpolated too, during the tessellation process?

Title: Bad lighting using Phong Method

Body:
I'm trying to make a cube, which is irregularly triangulated, but virtually coplanar, shade correctly.

Here is the current result I have:

With wireframe:

Normals calculated in my program:

Normals calculated by meshlabjs.net:

The lighting works properly when using regular size triangles for the cube. As you can see, I'm duplicating vertices and using angle weighting.

lighting.frag

vec4 scene_ambient = vec4(1, 1, 1, 1.0);

struct material
{
  vec4 ambient;
  vec4 diffuse;
  vec4 specular;
  float shininess;
};

material frontMaterial = material(
  vec4(0.25, 0.25, 0.25, 1.0),
  vec4(0.4, 0.4, 0.4, 1.0),
  vec4(0.774597, 0.774597, 0.774597, 1.0),
  76
);

struct lightSource
{
  vec4 position;
  vec4 diffuse;
  vec4 specular;
  float constantAttenuation, linearAttenuation, quadraticAttenuation;
  float spotCutoff, spotExponent;
  vec3 spotDirection;
};

lightSource light0 = lightSource(
  vec4(0.0,  0.0, 0.0, 1.0),
  vec4(100.0,  100.0,  100.0, 100.0),
  vec4(100.0,  100.0,  100.0, 100.0),
  0.1, 1, 0.01,
  180.0, 0.0,
  vec3(0.0, 0.0, 0.0)
);

vec4 light(lightSource ls, vec3 norm, vec3 deviation, vec3 position)
{
  vec3 viewDirection = normalize(vec3(1.0 * vec4(0, 0, 0, 1.0) - vec4(position, 1)));

  vec3 lightDirection;
  float attenuation;

  //ls.position.xyz = cameraPos;
  ls.position.z += 50;

  if (0.0 == ls.position.w) // directional light?
  {
    attenuation = 1.0; // no attenuation
    lightDirection = normalize(vec3(ls.position));
  }
  else // point light or spotlight (or other kind of light)
  {
      vec3 positionToLightSource = vec3(ls.position - vec4(position, 1.0));
    float distance = length(positionToLightSource);
    lightDirection = normalize(positionToLightSource);
    attenuation = 1.0 / (ls.constantAttenuation
      + ls.linearAttenuation * distance
      + ls.quadraticAttenuation * distance * distance);

    if (ls.spotCutoff <= 90.0) // spotlight?
    {
      float clampedCosine = max(0.0, dot(-lightDirection, ls.spotDirection));
      if (clampedCosine < cos(radians(ls.spotCutoff))) // outside of spotlight cone?
      {
        attenuation = 0.0;
        }
      else
        {
        attenuation = attenuation * pow(clampedCosine, ls.spotExponent);
        }
    }
  }

  vec3 ambientLighting = vec3(scene_ambient) * vec3(frontMaterial.ambient);

  vec3 diffuseReflection = attenuation
    * vec3(ls.diffuse) * vec3(frontMaterial.diffuse)
    * max(0.0, dot(norm, lightDirection));

  vec3 specularReflection;
  if (dot(norm, lightDirection) < 0.0) // light source on the wrong side?
  {
    specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
  }
  else // light source on the right side
  {
    specularReflection = attenuation * vec3(ls.specular) * vec3(frontMaterial.specular)
         * pow(max(0.0, dot(reflect(lightDirection, norm), viewDirection)), frontMaterial.shininess);
  }

  return vec4(ambientLighting + diffuseReflection + specularReflection, 1.0);
}

vec4 generateGlobalLighting(vec3 norm, vec3 position)
{
  return light(light0, norm, vec3(2,0,0), position);
}

mainmesh.frag

#version 430
in vec3 f_color;
in vec3 f_normal;
in vec3 f_position;

in float f_opacity;

out vec4 fragColor;

vec4 generateGlobalLighting(vec3 norm, vec3 position);

void main()
{
  vec3 norm = normalize(f_normal);
  vec4 l0 = generateGlobalLighting(norm, f_position);

  fragColor = vec4(f_color, f_opacity) * l0;
}

Follows the code to generate the verts, normals and faces for the painter.

m_vertices_buf.resize(m_mesh.num_faces() * 3, 3);
m_normals_buf.resize(m_mesh.num_faces() * 3, 3);
m_faces_buf.resize(m_mesh.num_faces(), 3);

std::map<vertex_descriptor, std::list<Vector3d>> map;
GLDebugging* deb = GLDebugging::getInstance();

auto getAngle = [](Vector3d a, Vector3d b) {
    double angle = 0.0;
    angle = std::atan2(a.cross(b).norm(), a.dot(b));
    return angle;
};

for (const auto& f : m_mesh.faces()) {
    auto f_hh = m_mesh.halfedge(f);
    //auto n = PMP::compute_face_normal(f, m_mesh);

    vertex_descriptor vs[3];
    Vector3d ps[3];

    int i = 0;
    for (const auto& v : m_mesh.vertices_around_face(f_hh)) {
        auto p = m_mesh.point(v);
        ps[i] = Vector3d(p.x(), p.y(), p.z());
        vs[i++] = v;
    }

    auto n = (ps[1] - ps[0]).cross(ps[2] - ps[0]).normalized();

    auto a1 = getAngle((ps[1] - ps[0]).normalized(), (ps[2] - ps[0]).normalized());
    auto a2 = getAngle((ps[2] - ps[1]).normalized(), (ps[0] - ps[1]).normalized());
    auto a3 = getAngle((ps[0] - ps[2]).normalized(), (ps[1] - ps[2]).normalized());

    auto area = PMP::face_area(f, m_mesh);

    map[vs[0]].push_back(n * a1);
    map[vs[1]].push_back(n * a2);
    map[vs[2]].push_back(n * a3);

    auto p = m_mesh.point(vs[0]);
    deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);

    p = m_mesh.point(vs[1]);
    deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);

    p = m_mesh.point(vs[2]);
    deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);
}

int j = 0;
int i = 0;
for (const auto& f : m_mesh.faces()) {
    auto f_hh = m_mesh.halfedge(f);
    for (const auto& v : m_mesh.vertices_around_face(f_hh)) {
        const auto& p = m_mesh.point(v);
        m_vertices_buf.row(i) = RowVector3d(p.x(), p.y(), p.z());

        Vector3d n(0, 0, 0);

        //auto n = PMP::compute_face_normal(f, m_mesh);
        Vector3d norm = Vector3d(n.x(), n.y(), n.z());

        for (auto val : map[v]) {
            norm += val;
        }

        norm.normalize();

        deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(norm.x(), norm.y(), norm.z()) * 3,
            Vector3d(1.0, 0, 0));

        m_normals_buf.row(i++) = RowVector3d(norm.x(), norm.y(), norm.z());
    }

    m_faces_buf.row(j++) = RowVector3i(i - 3, i - 2, i - 1);
}

Follows the painter code:

m_vertexAttrLoc = program.attributeLocation("v_vertex");
m_colorAttrLoc = program.attributeLocation("v_color");
m_normalAttrLoc = program.attributeLocation("v_normal");

m_mvMatrixLoc = program.uniformLocation("v_modelViewMatrix");
m_projMatrixLoc = program.uniformLocation("v_projectionMatrix");
m_normalMatrixLoc = program.uniformLocation("v_normalMatrix");
//m_relativePosLoc = program.uniformLocation("v_relativePos");
m_opacityLoc = program.uniformLocation("v_opacity");
m_colorMaskLoc = program.uniformLocation("v_colorMask");

//bool for unmapping depth color
m_useDepthMap = program.uniformLocation("v_useDepthMap");
program.setUniformValue(m_mvMatrixLoc, modelView);

//uniform used for Color map to regular model switch
program.setUniformValue(m_useDepthMap, (m_showColorMap &&
    (m_showProblemAreas || m_showPrepMap || m_showDepthMap || m_showMockupMap)));

QMatrix3x3 normalMatrix = modelView.normalMatrix();
program.setUniformValue(m_normalMatrixLoc, normalMatrix);
program.setUniformValue(m_projMatrixLoc, projection);

//program.setUniformValue(m_relativePosLoc, m_relativePos);
program.setUniformValue(m_opacityLoc, m_opacity);
program.setUniformValue(m_colorMaskLoc, m_colorMask);

glEnableVertexAttribArray(m_vertexAttrLoc);
m_vertices.bind();
glVertexAttribPointer(m_vertexAttrLoc, 3, GL_DOUBLE, false, 3 * sizeof(GLdouble), NULL);
m_vertices.release();

glEnableVertexAttribArray(m_normalAttrLoc);
m_normals.bind();
glVertexAttribPointer(m_normalAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
m_normals.release();

glEnableVertexAttribArray(m_colorAttrLoc);

if (m_showProblemAreas) {
    m_problemColorMap.bind();
    glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    m_problemColorMap.release();
}
else if (m_showPrepMap) {
    m_prepColorMap.bind();
    glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    m_prepColorMap.release();
}
else if (m_showMockupMap) {
    m_mokupColorMap.bind();
    glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    m_mokupColorMap.release();
}
else {
    //m_colors.bind();
    //glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
    //m_colors.release();
}

m_indices.bind();
glDrawElements(GL_TRIANGLES, m_indices.size() / sizeof(int), GL_UNSIGNED_INT, NULL);
m_indices.release();

glDisableVertexAttribArray(m_vertexAttrLoc);
glDisableVertexAttribArray(m_normalAttrLoc);
glDisableVertexAttribArray(m_colorAttrLoc);

EDIT: Sorry for not being clear enough. The cube is merely an example. My requirements are that the shading works for any kind of mesh. Those with very sharp edges, and those that are very organic (like humans or animals).

Body:
The issue is clearly explained by the image "Normals calculated in my program" from your question. The normal vectors at the corners and edges of the cube are not normal perpendicular to the faces:

For a proper specular reflection on plane faces, the normal vectors have to be perpendicular to the sides of the cube.

The vertex coordinate and its normal vector from a tuple with 6 components (x, y, z, nx, ny, nz).
A vertex coordinate on an edge of the cube is adjacent to 2 sides of the cube and 2 (face) normal vectors. The 8 vertex coordinates on the 8 corners of the cube are adjacent to 3 sides (3 normal vectors) each.

To define the vertex attributes with face normal vectors (perpendicular to a side) you have to define multiple tuples with the same vertex coordinate but different normal vectors. You have to use the different attribute tuples to form the triangle primitives on the different sides of the cube.

e.g. If you have defined a cube with the left, front, bottom coordinate of (-1, -1, -1) and the right, back, top coordinate of (1, 1, 1), then the vertex coordinate (-1, -1, -1) is adjacent to the left, front and bottom side of the cube:

         x  y  z   nx ny nz
left:   -1 -1 -1   -1  0  0
front:  -1 -1 -1    0 -1  0
bottom: -1 -1 -1    0  0 -1

Use the left attribute tuple to form the triangle primitives on the left side, the front to form the front and bottom for the triangles on the bottom.

In general you have to decide what you want. There is no general approach for all meshes.

Either you have a fine granulated mesh and you want a smooth appearance (e.g a sphere). In that case your approach is fine, it will generate a smooth light transition on the edges between the primitives.

Or you have a mesh with hard edges like a cube. In that case you have to "duplicate" vertices. If 2 (or even more) triangles share a vertex coordinate, but the face normal vectors are different, then you have to create a separate tuple, for all the combinations of the vertex coordinate and the face normal vector.

For a general "smooth" solution you would have to interpolate the normal vectors of the vertex coordinates which are in the middle of plane surfaces, according to the surrounding geometry. That means if a bunch of triangle primitives form a plane, then all the normal vectors of the vertices have to be computed dependent on there position on the plane. At the centroid the normal vector is equal to the face normal vector. For all other points the normal vector has to be interpolated with the normal vectors of the surrounding faces.

Anyway that seems to be an XY problem. Why is there a "vertex" somewhere in the middle of a plane? Probably the plane is tessellated. But if the plan is tessellated, why are the normal vectors not interpolated too, during the tessellation process?


来源: stackexchange

问:
Print option for each item in array
I have an array and for each item in the array, I'm trying to add in a new <option>.

To do so, I've tried the following:

```<code> array.forEach(function(arr) {
   console.log(array);
   $(".filterSection .department").append('<option value="'+array+'">'+array+'</option>');
 });
</code>```

However, the option is just printing with all the array values in the <option>. It creates new option tags, but their value and text is all the items in the array.

Full demo:

var array = ["Value 1", "Value 2", "Value 3"];

array.forEach(function(arr) {
  console.log(array);
  $(".department").append('<option value="' + array + '">' + array + '</option>');
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<select class="department" name="department" id="department"></select></code>```

Where am I going wrong?

答:
You should use arr which represents single array element instead of array:

var array = ["Value 1", "Value 2", "Value 3"];

array.forEach(function(arr) {
  $(".department").append('<option value="' + arr + '">' + arr + '</option>');
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="department" name="department" id="department"></select></code>```

ContentLicense: CC BY-SA 4.0

Title: Print option for each item in array

Body:
I have an array and for each item in the array, I'm trying to add in a new <option>.

To do so, I've tried the following:

 array.forEach(function(arr) {
   console.log(array);
   $(".filterSection .department").append('<option value="'+array+'">'+array+'</option>');
 });

However, the option is just printing with all the array values in the <option>. It creates new option tags, but their value and text is all the items in the array.

Full demo:

var array = ["Value 1", "Value 2", "Value 3"];

array.forEach(function(arr) {
  console.log(array);
  $(".department").append('<option value="' + array + '">' + array + '</option>');
});

<select class="department" name="department" id="department"></select>

Where am I going wrong?

Body:
You should use arr which represents single array element instead of array:

var array = ["Value 1", "Value 2", "Value 3"];

array.forEach(function(arr) {
  $(".department").append('<option value="' + arr + '">' + arr + '</option>');
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="department" name="department" id="department"></select>


问:
What is the Ideal way to return data from function without leaking memory?
In IPhone Development ObjC , I wonder what is the right approach for functions to return some values in Dictionaries or Arrays. I mean should they return autorelease objects, but wouldn't it be bad if I am using too many functions to return values, like getUserRecordsFromDB() function will return all the user records, so should they return me autorelease objects? also when I am calling them multiple times, suppose with a span of 4 seconds to get the newely updated data. Can somebody let me an ideal scanario of how to get data from a function called frequently in the flow of program, and not leaking the memory.</p>

答:
We should always return autorelease objects from functions and ensure they get released by setting up Autorelease pool in the calling function as follows

```<code>NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// Call database function here...

[pool release];
</code>```

Refer the auto release pool documentation here

ContentLicense: CC BY-SA 3.0

Body:
We should always return autorelease objects from functions and ensure they get released by setting up Autorelease pool in the calling function as follows

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// Call database function here...

[pool release];

Refer the auto release pool documentation here


问:
Button appears only when on the dashboard route?
I have a button on a navbar, that navbar will appear on all screens. However, I would like the button to appear only on the dashboard screen.

Currently, routes are done with the react-router-dom

The button is the <Button>Últimos 30 dias</Button>

HTML:

```<code>export default function NavBar() {
  return (
    <Box>
      <NavBarLeft>
        <Hamburger>
          <MenuIcon style={{ color: "#0ed39c", fontSize: "30px" }} />
        </Hamburger>

        <Button>Últimos 30 dias</Button>
      </NavBarLeft>

      <Profile />
    </Box>
  );
}
</code>```

CSS:

```<code>export const Box = styled.div`
  padding-left: 30px;
  padding-right: 30px;
  height: 75px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #fff;
  box-shadow: 0 4px 16px rgba(69, 91, 99, 0.06);
`;

export const NavBarLeft = styled.div`
  display: flex;
  align-items: center;
`;

export const Hamburger = styled.div`
  margin-right: 30px;
`;

export const Button = styled.button`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-top: 4px;
  padding-left: 15px;

  padding-right: 15px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid ${props => props.theme.colors.marketplace};

  font-size: 18px;
  line-height: 22px;
  color: ${props => props.theme.colors.marketplace};
`;
</code>```

答:
You can do it like this.</p>

```<code>import { useLocation } from 'react-router-dom';

export default function NavBar() {
 const location = useLocation();

  return (
    <Box>
      <NavBarLeft>
        <Hamburger>
          <MenuIcon style={{ color: "#0ed39c", fontSize: "30px" }} />
        </Hamburger>

        { location.path === '/dashboard' && <Button>Últimos 30 dias</Button> }
      </NavBarLeft>

      <Profile />
    </Box>
  );
}
</code>```

Body:
I have a button on a navbar, that navbar will appear on all screens. However, I would like the button to appear only on the dashboard screen.

Currently, routes are done with the react-router-dom

The button is the <Button>Últimos 30 dias</Button>

HTML:

export default function NavBar() {
  return (
    <Box>
      <NavBarLeft>
        <Hamburger>
          <MenuIcon style={{ color: "#0ed39c", fontSize: "30px" }} />
        </Hamburger>

        <Button>Últimos 30 dias</Button>
      </NavBarLeft>

      <Profile />
    </Box>
  );
}

CSS:

export const Box = styled.div`
  padding-left: 30px;
  padding-right: 30px;
  height: 75px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #fff;
  box-shadow: 0 4px 16px rgba(69, 91, 99, 0.06);
`;

export const NavBarLeft = styled.div`
  display: flex;
  align-items: center;
`;

export const Hamburger = styled.div`
  margin-right: 30px;
`;

export const Button = styled.button`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-top: 4px;
  padding-left: 15px;

  padding-right: 15px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid ${props => props.theme.colors.marketplace};

  font-size: 18px;
  line-height: 22px;
  color: ${props => props.theme.colors.marketplace};
`;

Body:
You can do it like this.

import { useLocation } from 'react-router-dom';

export default function NavBar() {
 const location = useLocation();

  return (
    <Box>
      <NavBarLeft>
        <Hamburger>
          <MenuIcon style={{ color: "#0ed39c", fontSize: "30px" }} />
        </Hamburger>

        { location.path === '/dashboard' && <Button>Últimos 30 dias</Button> }
      </NavBarLeft>

      <Profile />
    </Box>
  );
}


问:
Attach DOM elements to other DOM elements only after they have loaded
I am trying to write the code to do the following:

When the user uploads the images, return previews of those images as canvas elements. (This is taken care of by loadImage API)

Attach div elements next to each of those canvases.

To do the above in order, I will need to invoke document.querySelectorAll method only after the canvas elements are fully drawn.

Here is the code I wrote. I tried to use promise here, but apparently the promise is resolved after the loadImage functions are invoked, not after the canvas elements are fully drawn. When I run the function, the previews are populated as canvas elements, but the 'photo_order' div elements are not attached.

```<code>function rpu() {
  let promise = new Promise(async function(resolve, reject) {
    let filez = e.target.files;
    let files = Array.from(filez);
    files.forEach(function(file) {
      loadImage(
        file,
        function(img) {
          document.querySelector('#r_im_preview').appendChild(img);
          document.querySelector('#r_im_preview').classList.remove('hide');
        }, {
          maxWidth: 150,
          orientation: true,
          contain: true
        }
      )
    });
    resolve();
  });
  promise.then(function() {
    let k1 = document.querySelectorAll('canvas');
    let k2 = Array.from(k1);
    let k3 = '<div class="photo_order" style="cursor: pointer;"></div>'
    k2.forEach(k => {
      k.insertAdjacentHTML('afterEnd', k3);
    })
  });
}
</code>```

How do I fix the code to achieve what I am trying to do? Any advice will be very much welcome.

答:
I think you need to refactor your code to correctly use promises. Something like this:

const appendPreview = (img) => {
    document.querySelector('#r_im_preview').appendChild(img)
    document.querySelector('#r_im_preview').classList.remove('hide');
}

const loadImageP = (file, cb, settings) => new Promise((resolve, reject) => {
    try {
        const cbP = (...args) => (cb(...args), resolve)
        loadImage(file, cbP, settings)
    } catch {
        reject()
    }
})

const settings = {
    maxWidth: 150
    orientation: true,
    contain: true
}

async function rpu() {
    const promises = [...e.target.files].reduce((acc, file) =>
        [...acc, loadImageP(file, appendPreview, settings))], [])

    await Promise.all(promises)

    let canvasNodes = document.querySelectorAll('canvas');
    let orderNode = '

'
    [...canvasNodes].forEach((n) => { n.insertAdjacentHTML('afterEnd', orderNode);
}
```

Body:
I am trying to write the code to do the following:

When the user uploads the images, return previews of those images as canvas elements. (This is taken care of by loadImage API)

Attach div elements next to each of those canvases.

To do the above in order, I will need to invoke document.querySelectorAll method only after the canvas elements are fully drawn.

Here is the code I wrote. I tried to use promise here, but apparently the promise is resolved after the loadImage functions are invoked, not after the canvas elements are fully drawn. When I run the function, the previews are populated as canvas elements, but the 'photo_order' div elements are not attached.

function rpu() {
  let promise = new Promise(async function(resolve, reject) {
    let filez = e.target.files;
    let files = Array.from(filez);
    files.forEach(function(file) {
      loadImage(
        file,
        function(img) {
          document.querySelector('#r_im_preview').appendChild(img);
          document.querySelector('#r_im_preview').classList.remove('hide');
        }, {
          maxWidth: 150,
          orientation: true,
          contain: true
        }
      )
    });
    resolve();
  });
  promise.then(function() {
    let k1 = document.querySelectorAll('canvas');
    let k2 = Array.from(k1);
    let k3 = '

'
    k2.forEach(k => {
      k.insertAdjacentHTML('afterEnd', k3);
    })
  });
}

How do I fix the code to achieve what I am trying to do? Any advice will be very much welcome.

Body:
I think you need to refactor your code to correctly use promises. Something like this:

const appendPreview = (img) => {
    document.querySelector('#r_im_preview').appendChild(img)
    document.querySelector('#r_im_preview').classList.remove('hide');
}

const loadImageP = (file, cb, settings) => new Promise((resolve, reject) => {
    try {
        const cbP = (...args) => (cb(...args), resolve)
        loadImage(file, cbP, settings)
    } catch {
        reject()
    }
})

const settings = {
    maxWidth: 150
    orientation: true,
    contain: true
}

async function rpu() {
    const promises = [...e.target.files].reduce((acc, file) =>
        [...acc, loadImageP(file, appendPreview, settings))], [])

    await Promise.all(promises)

    let canvasNodes = document.querySelectorAll('canvas');
    let orderNode = '<div class="photo_order" style="cursor: pointer;"></div>'
    [...canvasNodes].forEach((n) => { n.insertAdjacentHTML('afterEnd', orderNode);
}


问:
no such column sqlite selectquery
I'm using a select query to get the user details from an sqlite databse from a username for verification of login details using the following code:

```<code>    @post('/login/attempt')
    def processLogin():
        submittedUsername = request.forms.get("Username")
        submittedPassword = request.forms.get("Password")
        data = c.execute("SELECT * FROM Users WHERE Users.username =
                         {}".format(submittedUsername)).fetchone()
</code>```

I get the error OperationalError ('no such column: janedoe')
janedoe is the username I've been putting in to the form.

I don't understand why this would be looking for a column with that name. As far as I understand this should be looking for a row in which the value in the username column is "janedoe".

答:
Not sure if your query is correct, I think what you are trying to do is : </p>

```<code>c.execute('SELECT * FROM Users WHERE username=?', (submittedUsername,)).fetchone()
</code>```

<p>Hope this helps </p>

Title: no such column sqlite selectquery

Body:
I'm using a select query to get the user details from an sqlite databse from a username for verification of login details using the following code:

    @post('/login/attempt')
    def processLogin():
        submittedUsername = request.forms.get("Username")
        submittedPassword = request.forms.get("Password")
        data = c.execute("SELECT * FROM Users WHERE Users.username =
                         {}".format(submittedUsername)).fetchone()

I get the error OperationalError ('no such column: janedoe')
janedoe is the username I've been putting in to the form.

I don't understand why this would be looking for a column with that name. As far as I understand this should be looking for a row in which the value in the username column is "janedoe".

Body:
Not sure if your query is correct, I think what you are trying to do is :

c.execute('SELECT * FROM Users WHERE username=?', (submittedUsername,)).fetchone()

Hope this helps


问:
Floating on both sides separately without interfering
I would like to decorate and shape the left and right borders of my text using float and clear properties. To start I have this markup which looks like the left and right stair steps should both start at the top of the page. However, the stairs aren't vertically aligned; the second stairs seem to always start drawing at the second-to-last step on the other side.

Left

Left Two

Left Number Three

Right

Right Two

Right Number Three

... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... .```

The result (same in Chrome + Firefox):

I'd like the stairs to both start at the beginning, as they seem like they should, since I'm only clearing floats on the side they're on. Note that I'm not just shaping the borders, I'm also showing important things on the shaped sides.

答:
A floated element isn't positioned independently of the document flow - it's vertically placed wherever the preceding element is (be it a block, floated or not, or inline content) - in the flow of elements inside the document.

So what you are looking for (floated elements with content floating around it, but independently left and right independent from the document flow) is basically impossible.

EDIT:

Here's the code from the comment below, with some longer text in it to show what I mean:

div,
p {
  font-size: 24px;
  margin: 0;
  text-align: center;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div style="float: left; clear: left; background: green;">Left</div>
<div style="float: right; clear: right; background: red;">Right</div>
<p>Some text in between</p>
<div style="float: left; clear: left; background: green;">Left Two</div>
<div style="float: right; clear: right; background: red;">Right Two</div>
<p>Some more text in between. Some more text in between,  in between,  in between. Some more text in between. </p>
<div style="float: left; clear: left; background: green;">Left Number Three</div>
<div style="float: right; clear: right; background: red;">Right Number Three</div>
<p>And again less text in between.</p></code>```

So a workaround like that can only work with a very little amount of content/text (or none) in between. (Note also that I set the p's margins to 0, otherwise there would be whitespace between the "steps".)

Body:
I would like to decorate and shape the left and right borders of my text using float and clear properties. To start I have this markup which looks like the left and right stair steps should both start at the top of the page. However, the stairs aren't vertically aligned; the second stairs seem to always start drawing at the second-to-last step on the other side.

Left

Left Two

Left Number Three

Right

Right Two

Right Number Three

... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... .

The result (same in Chrome + Firefox):

I'd like the stairs to both start at the beginning, as they seem like they should, since I'm only clearing floats on the side they're on. Note that I'm not just shaping the borders, I'm also showing important things on the shaped sides.

Body:
A floated element isn't positioned independently of the document flow - it's vertically placed wherever the preceding element is (be it a block, floated or not, or inline content) - in the flow of elements inside the document.

So what you are looking for (floated elements with content floating around it, but independently left and right independent from the document flow) is basically impossible.

EDIT:

Here's the code from the comment below, with some longer text in it to show what I mean:

div,
p {
  font-size: 24px;
  margin: 0;
  text-align: center;
}

<div style="float: left; clear: left; background: green;">Left</div>
<div style="float: right; clear: right; background: red;">Right</div>
<p>Some text in between</p>
<div style="float: left; clear: left; background: green;">Left Two</div>
<div style="float: right; clear: right; background: red;">Right Two</div>
<p>Some more text in between. Some more text in between,  in between,  in between. Some more text in between. </p>
<div style="float: left; clear: left; background: green;">Left Number Three</div>
<div style="float: right; clear: right; background: red;">Right Number Three</div>
<p>And again less text in between.</p>

So a workaround like that can only work with a very little amount of content/text (or none) in between. (Note also that I set the p's margins to 0, otherwise there would be whitespace between the "steps".)


问:
How can I avoid styling the footer?
I have styles for the site but don't want them to apply to the footer. How can I achieve this?

HTML CSS Selector

```<code>@media(max-width: 500px){
#mobileview{
width:100%;
height:211px;
}

p {
    text-align: left;
    text-align: justify;
    font-size:70%;
}
br {
    display: none;
}
h1 {
    text-align: left;
    font-size:190%;

}
a {
    text-align: left;

        float:left;
}
a.animation {
    text-align: center;
        font-size:9px;
        float:center;

}
}
</code>```

This is one of the code for my mobile view.

This is my code when calling footer

```<code><div class="row">
  <div class="container2">
   XXX Content
  </div>
</div>
<?php echo $footer; ?>
</code>```

How do i exclude these style for footer ?  As it was messing with my footer

答:
You cannot exclude styles for when elements match that reside in a specific context (blacklisting is not possible because there is no parent selector in CSS)

What you can go for, is a whitelisting approach, namely give your selectors context:

main p {
  color: red;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><main>
  <p>I'm red</p>
</main>
<footer>
  <p>I'm not red</p>
</footer></code>```

In this example, instead of doing

```<code>p { color: red; }
</code>```

notice how I define the context that says only p inside main shall be affected by this rule.

```<code>main p { color: red; }
</code>```

Title: How can I avoid styling the footer?

Body:
I have styles for the site but don't want them to apply to the footer. How can I achieve this?

HTML CSS Selector

@media(max-width: 500px){
#mobileview{
width:100%;
height:211px;
}

p {
    text-align: left;
    text-align: justify;
    font-size:70%;
}
br {
    display: none;
}
h1 {
    text-align: left;
    font-size:190%;

}
a {
    text-align: left;

        float:left;
}
a.animation {
    text-align: center;
        font-size:9px;
        float:center;

}
}

This is one of the code for my mobile view.

This is my code when calling footer

   XXX Content

<?php echo $footer; ?>

How do i exclude these style for footer ?  As it was messing with my footer

Body:
You cannot exclude styles for when elements match that reside in a specific context (blacklisting is not possible because there is no parent selector in CSS)

What you can go for, is a whitelisting approach, namely give your selectors context:

main p {
  color: red;
}

<main>
  <p>I'm red</p>
</main>
<footer>
  <p>I'm not red</p>
</footer>

In this example, instead of doing

p { color: red; }

notice how I define the context that says only p inside main shall be affected by this rule.

main p { color: red; }


问:
How to increment a value in ngfor angular 6 for every third iteration
How to increment a value for every 3rd iteration in ngFor.

 I want to achieve like this in angular ngfor, how to do this

I am using array of objects like below and I am looping tempArr[] using ngFor

  tempArrA = ['item a', 'item b', 'item c', 'item d', 'item e', 'item f', 'item g', 'item h','item i', 'item j', 'item k', 'item l','item m', 'item n', 'item o', 'item p'];
  tempArrB = ['item f', 'item g', 'item h','item i', 'item j'];
  tempArrC = [ 'item j', 'item k', 'item l','item m', 'item n', 'item o', 'item p'];
  tempArr:any = [
    {
      name: "one",
      items: this.tempArrA
      },
       {
      name: "two",
      items: this.tempArrB
      },
       {
      name: "three",
      items: this.tempArrC
      },
      ];```

item a -- 1

item b -- 1

item c -- 1

item d -- 2

item e -- 2

item f -- 2

item g -- 3

item h -- 3

item i -- 3

and so on....

答:
You can use this by using angular pipe.

.html

```<code><div *ngFor="let data of tempArrA; let i = index">
  {{data | format : i}}
</div>
</code>```

.pipe

```<code>    import { Pipe, PipeTransform } from '@angular/core';

    @Pipe({
      name: 'format'
    })
    export class FormatPipe implements PipeTransform {
        transform(value: any, args?: any): any {
          let d = Math.floor(args / 3) + 1
          return value + d;
        }
    }
</code>```

This pipe will take value as array value and an argument which will be index. In pipe a variable is initialized with value = 0. Than check index%3 === 0 at this time increment that initialized value by 1 and return by concatinating
check working link

https://stackblitz.com/edit/angular-snhcfv?embed=1&file=src/app/app.component.html

Body:
How to increment a value for every 3rd iteration in ngFor.

 I want to achieve like this in angular ngfor, how to do this

I am using array of objects like below and I am looping tempArr[] using ngFor

  tempArrA = ['item a', 'item b', 'item c', 'item d', 'item e', 'item f', 'item g', 'item h','item i', 'item j', 'item k', 'item l','item m', 'item n', 'item o', 'item p'];
  tempArrB = ['item f', 'item g', 'item h','item i', 'item j'];
  tempArrC = [ 'item j', 'item k', 'item l','item m', 'item n', 'item o', 'item p'];
  tempArr:any = [
    {
      name: "one",
      items: this.tempArrA
      },
       {
      name: "two",
      items: this.tempArrB
      },
       {
      name: "three",
      items: this.tempArrC
      },
      ];

item a -- 1

item b -- 1

item c -- 1

item d -- 2

item e -- 2

item f -- 2

item g -- 3

item h -- 3

item i -- 3

and so on....

Body:
You can use this by using angular pipe.

.html

<div *ngFor="let data of tempArrA; let i = index">
  {{data | format : i}}
</div>

.pipe

    import { Pipe, PipeTransform } from '@angular/core';

    @Pipe({
      name: 'format'
    })
    export class FormatPipe implements PipeTransform {
        transform(value: any, args?: any): any {
          let d = Math.floor(args / 3) + 1
          return value + d;
        }
    }

This pipe will take value as array value and an argument which will be index. In pipe a variable is initialized with value = 0. Than check index%3 === 0 at this time increment that initialized value by 1 and return by concatinating
check working link

https://stackblitz.com/edit/angular-snhcfv?embed=1&file=src/app/app.component.html


问:
Disable Thunderbird Folder Expansion
I have recently setup Thunderbird in my machine.

I have setup two accounts, one for me and the other for my brother.

Is it possible to disable the expansion of the node for my Folder when I am not logged in to the gmail account?

I am asking this to provide privacy in between our folders.

Or would it be possible to set up Thunderbird so that when you open thunderbird, you can select which account to open and enter password. only then the account which you chose to open can be viewed.

If the password you supplied for an account is not correct, then you cannot view that folder or email of that account.

答:
Erm... Isn't that what multiple computer user accounts are for?

Why are you sharing your computer account, but then want privacy in mail?

ContentLicense: CC BY-SA 2.5

Title: Disable Thunderbird Folder Expansion

OwnerDisplayName: Tomalak


问:
php java batch processing
I work in Linux. I have 3 file (about 2Gb each containing human genome sequence). I have java codes to process those files via web interface developed in PHP. The processing time is about 24 hours or even more.

How can i run the Java code from PHP so that the processing does not terminate when I close the browser.

Since the processing time is so long, it is not practicable to keep the browser open until the process get completed.

I assume it requires batch processing.

答:
In Unix/Linux, if you want to start a process that runs on the background, you must add & character at the end of the command.

```<code>> java blabla &
</code>```

so, call shell_execute() like this:

```<code>shell_execute('java blabla &')
</code>```

So it will continue processing after your script ended.

Title: php java batch processing

Body:
In Unix/Linux, if you want to start a process that runs on the background, you must add & character at the end of the command.

> java blabla &

so, call shell_execute() like this:

shell_execute('java blabla &')

So it will continue processing after your script ended.


问:
WAR file not compatible with manual installation of Tomcat
I have a WAR file that I created with Eclipse (it contains a website built with Struts 2). I developed and tested it on an Apache Tomcat 7.0.76 installation I did using Yum (my OS is CentOS). I then sent it to the client who experienced the following exception when trying to log in (the login page is displayed properly, the exception only occurs when trying to login):

```<code>HTTP Status 500 – Internal Server Error

Type Exception Report

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

java.lang.reflect.InvocationTargetException
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:270)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)

Root Cause

java.lang.ExceptionInInitializerError
    myproject.LoginAction.execute(LoginAction.java:48)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:270)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)

Root Cause

java.lang.RuntimeException: javax.naming.NamingException: Could not load resource factory class [Root exception is java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSourceFactory][Ljava.lang.StackTraceElement;@3e5f977b
    myproject.ConnectionDB.<clinit>(ConnectionDB.java:72)
    myproject.LoginAction.execute(LoginAction.java:48)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:270)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)

</code>```

Her Tomcat is installed manually using the zip file available on the Tomcat website. I tried to install the same version of Tomcat she uses (7.0.100) and got the same error. I then tried 7.0.90, and got the same error. I then tried to install the 7.0.76 using the zip file and... Got the error. But if I go back to my Tomcat 7.076 installed with Yum, it works as intended.

Is this a configuration problem ?

PS: the client is using Ubuntu

答:
The relevant part of the exception is this:

```<code>Could not load resource factory class [Root exception is java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSourceFactory][Ljava.lang.StackTraceElement;@3e5f977b
myproject.ConnectionDB.<clinit>(ConnectionDB.java:72)
</code>```

It seems that you use the commons-dbcp library and it is installed on your tomcat instance, but not on the others

Body:
I have a WAR file that I created with Eclipse (it contains a website built with Struts 2). I developed and tested it on an Apache Tomcat 7.0.76 installation I did using Yum (my OS is CentOS). I then sent it to the client who experienced the following exception when trying to log in (the login page is displayed properly, the exception only occurs when trying to login):

HTTP Status 500 – Internal Server Error

Type Exception Report

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

java.lang.reflect.InvocationTargetException
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:270)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)

Root Cause

java.lang.ExceptionInInitializerError
    myproject.LoginAction.execute(LoginAction.java:48)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:270)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)

Root Cause

java.lang.RuntimeException: javax.naming.NamingException: Could not load resource factory class [Root exception is java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSourceFactory][Ljava.lang.StackTraceElement;@3e5f977b
    myproject.ConnectionDB.<clinit>(ConnectionDB.java:72)
    myproject.LoginAction.execute(LoginAction.java:48)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:270)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)

Her Tomcat is installed manually using the zip file available on the Tomcat website. I tried to install the same version of Tomcat she uses (7.0.100) and got the same error. I then tried 7.0.90, and got the same error. I then tried to install the 7.0.76 using the zip file and... Got the error. But if I go back to my Tomcat 7.076 installed with Yum, it works as intended.

Is this a configuration problem ?

PS: the client is using Ubuntu

Body:
The relevant part of the exception is this:

Could not load resource factory class [Root exception is java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSourceFactory][Ljava.lang.StackTraceElement;@3e5f977b
myproject.ConnectionDB.<clinit>(ConnectionDB.java:72)

It seems that you use the commons-dbcp library and it is installed on your tomcat instance, but not on the others


问:
Why does variable locate before the loop
Why is the position of a loop header relative to the body is different from its usual one? How come a loop variable appears before the loop?
The code is taken from various programs

```<code> n=reduce(operator.mul,[int(x) for x in str(n)],1)
 return value == sum(int(x) ** len(str(value)) for x in str(value))

</code>```

答:
It is, technically, not a loop. This is so-called comprehension syntax, borrowed into Python from Haskell (see comments for the full lineage). To follow traditions of math notation for sets, and distinguish a comprehension from a usual loop, loop-like enumerator comes in the end of the notation.

Find more of history of various comprehensions and generator expression  in Python here http://python-history.blogspot.com/2010/06/from-list-comprehensions-to-generator.html

NOTE. The first of your expression contains a list comprehension, the list comprehension is the first and the most popular pythonic comprehension. The second one contains a generator expression, which, though, originally were called generator comprehension, according to PEP 289.

Body:
Why is the position of a loop header relative to the body is different from its usual one? How come a loop variable appears before the loop?
The code is taken from various programs

 n=reduce(operator.mul,[int(x) for x in str(n)],1)
 return value == sum(int(x) ** len(str(value)) for x in str(value))