JSP with Inner class

D

Doug Schaible

I am trying to create a JSP that has a class in it. (kind of like a
function) I am having a lot of trouble getting it to work though. I
get this error: /tmp/jsp_servlet/_wlm/__call_sp_start_stop.java:117:
inner classes cannot have static declarations
public static void Command( String databaseURL,
java.sql.Connection db2, String command, String results) { //[
/wlm/call_sp_start_stop.jsp; Line: 31]

My code is below. Can someone please guide me in the right direction.
Thanks,
Doug




<%@ page import="java.sql.*" errorPage="error.jsp";%>
<%@ page import="java.util.*" %>

<%
String ErrorMessage ="NONE";

boolean Continue;
Continue = true;

String databaseURL = "";
String user = "";
String password = "";
String sqlid = "";
String schema = "";
String sp = "";
String action = "";
String command = "";
String results = "";

java.sql.Connection db2 = null;
java.sql.ResultSet rs;
PreparedStatement stmt1;

java.sql.Statement st;
int one = 1;
int sqlCode = 0;
int r = 0;

class Wlm{

public static void Command( String databaseURL, java.sql.Connection
db2, String command, String results) {

java.sql.Statement st2;
java.sql.ResultSet rs2;
int one2 = 1;
db2.close();
java.util.Properties properties = new java.util.Properties ();
properties.setProperty ("user", "xxxxx");
properties.setProperty ("password", "xxxxxx");
db2 = java.sql.DriverManager.getConnection (databaseURL,
properties);
((com.ibm.db2.jcc.DB2Connection)db2).setDB2ClientApplicationInformation("WLM_QUERY_WEB");


// set the path to our schema name so we can find our procedure
st2 = db2.createStatement();
st2.execute("SET CURRENT FUNCTION PATH DB2SYS");

CallableStatement stmtSP = db2.prepareCall("CALL
DB2SYS.DB2_COMMAND(?)");
stmtSP.setString(1, command.toUpperCase());
stmtSP.execute();

results = "";

rs2 = stmtSP.getResultSet();
while (rs2.next())
{
results = results + "<br>" + rs2.getString(one2);

}
}
}
//













try
{
databaseURL = request.getParameter("ssid");
user = request.getParameter("userid");
password = request.getParameter("password");
sqlid = request.getParameter("sqlid");
schema = request.getParameter("schema");
sp = request.getParameter("sp");
action = request.getParameter("action");
}
catch(Exception e)
{
//
}

//-- Load the JDBC driver class
Class.forName("com.ibm.db2.jcc.DB2Driver");



.... lots of code here that is working



//create command
if(action.equals("Start"))
{
command = "-start procedure(" + schema.trim() + "." + sp + ")";
}
else if(action.equals("Stop - Reject"))
{
command = "-stop procedure(" + schema.trim() + "." + sp + ")
action(reject)";
}
else if(action.equals("Stop - Queue"))
{
command = "-stop procedure(" + schema.trim() + "." + sp + ")
action(queue)";
}
else
{
Continue = false;
ErrorMessage = "Command action not know. Command aborted.";
}

}

//call sp
if( Continue )
{
Wlm.Command(databaseURL, db2, command, results);
}


// Close our DB2 Connection
if( Continue )
{
db2.close();
}






%>




<html>


<%
if (!Continue)
{
out.println("<h1>ERROR: </h1>" + ErrorMessage);
}
%>

<%
if (Continue)
{
out.println("<h1>Success: </h1><p>" + results);
out.println("<h3>Warning: </h3>" + ErrorMessage);

}
%>


</body>
</html>
 
K

kaeli

I am trying to create a JSP that has a class in it. (kind of like a
function) I am having a lot of trouble getting it to work though. I
get this error: /tmp/jsp_servlet/_wlm/__call_sp_start_stop.java:117:
inner classes cannot have static declarations
public static void Command( String databaseURL,
java.sql.Connection db2, String command, String results) { //[
/wlm/call_sp_start_stop.jsp; Line: 31]

My code is below. Can someone please guide me in the right direction.
Thanks,
Doug

Just as it says - you can't have a static method in an inner class. This
is an inner class because JSP compiles into a servlet class. So making a
class in there makes it into an inner class.
Is there some reason you declared Command as "public static void"?
If you did it just because that's how you learned to make a class, stop
that. Classes don't require static methods or even a main method. Use
"public void" for Command.
If you wanted a static method so instances share, make a separate class,
then include it in the JSP. I do that for my connection class. Package
it up, pop the path in the webserver, and include it like any other
library.

HTH

--
 
D

Doug Schaible

If you wanted a static method so instances share, make a separate class,
then include it in the JSP. I do that for my connection class. Package
it up, pop the path in the webserver, and include it like any other
library.

HTH

Do you have an example that you would be willing to share???

Thanks,
Doug
 
S

Scott Yanoff

Doug said:
I am trying to create a JSP that has a class in it. (kind of like a
function) I am having a lot of trouble getting it to work though. I
get this error: /tmp/jsp_servlet/_wlm/__call_sp_start_stop.java:117:
inner classes cannot have static declarations
public static void Command( String databaseURL,
java.sql.Connection db2, String command, String results) { //[
/wlm/call_sp_start_stop.jsp; Line: 31]

<%

class Wlm{

public static void Command( String databaseURL, java.sql.Connection
db2, String command, String results) {

I don't really recommend doing this as it is not a useful separation of
logic and presentation. In any case, declarations should be between <%!
and %> tags, not <% and %>.

HTH,
-Scott
 
K

kaeli

Do you have an example that you would be willing to share???

What, the connection class or just having my custom classes included in
JSP? I'll assume the latter...
I include a whole package of mine, with lots of classes, in my JSP.

You MUST package your classes to do this. To package your classes, put

package whatever;
on the first line of the class file.
Make sure your class is in a directory of the same name. Then include
that path in the classpath.

So, say I have a package named "kaeli". I have the following directories
on my server

/home/myHome/javaFiles/
/home/myHome/javaFiles/kaeli

In every class file in "/home/myHome/javaFiles/kaeli", there is the line
package kaeli;
at the top.
Then, my classpath is changed to
CLASSPATH=$CLASSPATH:/home/myHome/javaFiles
to compile.
Note that the path is the one right above the package, not the package
itself (because I am not using a jar). If you use jar, point it right to
the jar file, not the directory above. I prefer not to use jar for this,
as IPlanet is a PITA about reloading files without restarting the
webserver. FWIU, this is not an issue with Tomcat, and Tomcat may
require a jar, so see what works for you.

Anyway, then in my webserver (IPlanet/NES), there is a parameter for JVM
classpath. I put the same thing in the JVM classpath that I had used in
my classpath to compile.
Then in the JSP, I can just do
<%@ page import="kaeli.*" %>

and use my classes.
(Note that you may need to restart your webserver for it to see changes
to the class files if it caches them.)

So, say my class that has all my connection stuff is named "DB_Conn" and
has a constructor that sets everything up and a method named "connect".
In the JSP, I can just do
<%
DB_Conn db = new DB_Conn();
db.connect();
%>

I use IPlanet, so don't ask me if this works the same in Tomcat. :)
I assume you have to set up Tomcat's (or Apache's) JVM classpath and it
should work fine, though.

HTH
--
 
D

Doug Schaible

Great it is kind of working now. I don't get any errors in the JSP or
in the class file, but I don't think that the code in the class file
is running. I added some System.out.println("hello")'s to my class
file and they don't get written to the app server log like they do in
my jsp. I pass a couple of strings to my class and they should come
back changed, but they do not.

In C++ you have to place a '&' in from of parms that you want to pass
by reference, does Java have something simular???

Again thanks in advance for your help,

Doug
 
Z

znôrt

my jsp. I pass a couple of strings to my class and they should come
back changed, but they do not.

In C++ you have to place a '&' in from of parms that you want to pass
by reference, does Java have something simular???

In Java everything is always passed by value. If the argument is an
object, it's reference is passed, but still by value. This gives the
method full access to the object, an to it's own copy of the
reference, but there's no way to alter the reference held by the
caller.

Strings, on the other hand, are constants and cannot be changed.
Whatever you are doing to these strings, you end up changing your
"local" reference to point to any newly created String instance, but
the callers reference still points to the same old string, which is
unaffected.

regards
znôrt
 
D

dougjrs

So how can you pass a string back? You must be able to do this somehow.

Thanks,
Doug
 
Z

znôrt

So how can you pass a string back? You must be able to do this somehow.

You could use StringBuffer instead of String, since they can be
altered. A better approach is to use return values.

regards
znôrt
 
D

dougjrs

I am not sure that I know what retuen values are. Can you give an example?

I guess that I could make it return a string - I can do that right?

Doug
 
K

kaeli

Great it is kind of working now. I don't get any errors in the JSP or
in the class file, but I don't think that the code in the class file
is running. I added some System.out.println("hello")'s to my class
file and they don't get written to the app server log like they do in
my jsp. I pass a couple of strings to my class and they should come
back changed, but they do not.

You can't do that. Variables don't change like that. You'd need to
return a string.
As to getting output from the included class in the JSP, you can't use
System.out. System.out points to the wrong spot (a log file for the
server, IIRC).

If you want to output, you need to pass the JSPWriter and write to that
stream. It's a bit of a PITA.

Here's a method from one of my classes that does this.

public void outputColumnHeadersHtml(Writer o, boolean withTotal)
throws java.io.IOException
{
// if withTotal is true, include total column
o.write("\n");
o.write("<tr>\n");
// need one blank column, which will line up with the row headers
o.write("<th>&nbsp</th>");
Iterator i = this.COLUMN_V.iterator();
while (i.hasNext())
{
o.write("<th>"+(String)i.next() + "</th>\n");
}
if (withTotal)
o.write("<th>Total</th>\n");
o.write("\n</tr>\n");
o.flush();
}

And here's the call.

crosstab.outputColumnHeadersHtml(out, false);

--
 
K

kaeli

I am not sure that I know what retuen values are. Can you give an example?

I guess that I could make it return a string - I can do that right?

Doug

How to return a value:

In my class:

public boolean update () throws ClassNotFoundException, SQLException,
InstantiationException, IllegalAccessException
{
boolean success=false;
....
return success;
}

In the JSP
if (cObj.update())
{
...
}

You can return a string the same way
public String myClassMethod ...
{
String myString;
...
return myString;
}

In the JSP:
String myNewString = myClass.myClassMethod();

--
 
D

dougjrs

Ok, I am getting closer here, but now I get a "java.lang.NoSuchMethodError".
I must have something defined wrong, but I am not sure what it is.
My JSP:
<%@ page import="test.*" %>
......
//call sp
if( Continue )
{
System.out.println("before: " + results);
Wlm start = new Wlm();
results = start.Wlm(databaseURL, db2, command, results);
System.out.println("after: " + results);
}
......

Wlm.java:
package test;

import java.sql.* ;
import java.util.* ;
import com.ibm.* ;
public class Wlm{
public Wlm()
{
System.out.println("Hello World");
}
public String Wlm( String databaseURL, java.sql.Connection db2, String
command, String results)
{
System.out.println("Hello World");
try{
java.sql.Statement st2;
java.sql.ResultSet rs2;
int one2 = 1;
try{
Class.forName("com.ibm.db2.jcc.DB2Driver");
}
catch( ClassNotFoundException e ){
results = results + e.toString();
System.out.println(results);
return results;
}
db2.close();
.......
results = results + "in wlm";
rs2 = stmtSP.getResultSet();
while (rs2.next())
{
results = results + "<br>" + rs2.getString(one2);
}
return results;
}
catch (SQLException e)
{
results = results + e.toString();
System.out.println(results);
return results;
}
}
}


Error from web server:
java.lang.NoSuchMethodError: test.Wlm: method
Wlm(Ljava/lang/String;Ljava/sql/Connection;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
not found



Thanks,
Doug
 
K

kaeli

Ok, I am getting closer here, but now I get a "java.lang.NoSuchMethodError".
I must have something defined wrong, but I am not sure what it is.

You have a method with the same name as the constructor. You can't do
that, AFAIK. You can overload the constructor to take arguments, but
it's still a constructor and requires the "new" keyword and I don't
think it can return something.
Rename the non-constructor (the one that takes arguments and returns a
string) to something else, like Wlm_doIt or something.

Restart the web server after saving and recompiling to clear the cache
if needed. My IPlanet requires that. Not sure what other servers
require.

--
--
~kaeli~
Why do they lock gas station bathrooms? Are they afraid
someone will clean them?
http://www.ipwebdesign.net/wildAtHeart
http://www.ipwebdesign.net/kaelisSpace
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top