I'm new to Java and I need some advice/information on how to debug my Java Applet.
I have created a applet that simply updates a MySQL database. The applet seems to load in the web page with no errors. When I click on my button to update the database it seems to actually make the call to the applet, BUT nothing happens, i.e. no new inserts are made to the database, and the page returns properly.
I have taken the applet code and tested it in a Java desktop app. It works fine, no changes other than removing the "extend Applet" modifier. In the desktop app the database gets updated properly.
If I was given some pointers on how to write to the Java Console window that might help me in debugging the code - but I don't know how to do that. I'm not sure what else to try to find the issue. Everything seems correct to me.
BTW: I'm using Netbeans 6.7 in Windows 7 with the MySQL server and Glassfish 2.1 on a CENTOS (Linux) system.
Here is my code for the applet:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.me.db;
import java.applet.*;
import java.sql.*;
/**
*
* #author Rick
*/
public class dbapplet extends Applet {
/**
* Initialization method that will be called after the applet is loaded
* into the browser.
*/
public void init() {
// TODO start asynchronous download of heavy resources
}
public long SaveToDatabase(String subject, String note, int priority,
String category, String isOpen, String currentSession) {
Connection con = null;
Statement stmt = null;
StringBuilder sb = new StringBuilder();
long lastInsertId = -1;
try {
//build the insert
int IsOpen = (isOpen.contains("1")) ? 1 : 2;
sb.append("INSERT INTO 'LogDetails' ('category', 'priority',
'subject', 'note', 'is_open', 'has_attachements') VALUES");
sb.append(" (");
sb.append("'" + category + "',");
sb.append(priority + ",");
sb.append("'" + subject + "',");
sb.append("'" + note + "',");
sb.append("b'" + IsOpen + "',");
sb.append("b'0');");
//connect and execute the insert
String dbURL = "jdbc:mysql://localhost/authentication";
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(dbURL, "xxxxxxx", "yyyyyyyy");
stmt = con.createStatement();
stmt.execute(sb.toString());
//get the last inserted id
ResultSet rs = null;
rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");
if (rs.next()) {
lastInsertId = rs.getLong(1);
}
rs.close();
} catch (Exception e) { //database problem
System.out.println("Error " + e.getMessage());
System.out.println(sb.toString());
}
return lastInsertId;
} //end of SaveToDatabase
public void QuickSaveToDataBase() {
//disgard the result for now - lets see if we can get this working
this.SaveToDatabase("Quick Save", "Testing of the Quick Save Function",
1, "Testing", "1", "skjdkjd-junk");
}
}
JDBC in Applet should be avoided if all possible. Here are the security issues you will be facing,
You have to open up your database to all IP addresses unless this is an inhouse or enterprise app.
Your database password will be in the applet, readable by anyone with a little reverse-engineering.
If you really want do this, you need to use trusted Applet by signing it.
Since you've got localhost as the server's address..., unless you're running the mysql server on the same box, this will cause a problem. Also, I believe there are security restrictions that disallow contacting localhost over a port from a Java Applet.
Hope this helps.
Applets run in a sandbox that (when in browser) dramatically restrict what they can do. In general, they can't open up connection to any host other than the one they were served up from.
This site: http://www.securingjava.com/chapter-two/chapter-two-2.html is a little dated, but gives you a good general idea for what restrictions you'll be facing.
The most likely reason for the failure is a classloader exception. The applet's classloader is a URLClassloader that can load classes only from certain URLs due to the security implications.
In this case, the applet classloader is most likely unable to load the MySQL JDBC driver. If you have to make the applet work, place the MySQL driver's jar files in an area on the web server that is accessible by the applet, and use the archive attribute of the applet tag to enable the classloader to load the driver.
Why should you not do this?
Although the answer given above will work technically, it is a really bad practice to expose your database on the internet or a DMZ(de-militarized zone); that normally includes an intranet as well in certain companies. Presumably, you are doing this for studying applets and not for production usage. ZZ Coder has already pointed this out.
Related
I'm working on a Java project that uses an Oracle database. When I create a new Oracle driver:
jdbcDriver driver = new jdbcDriver();
...I check it to see if it is valid using:
if (!driver.isValid())
{
throw new UncheckedSqlException("jdbcDriver not valid");
}
What is the correct procedure if the driver is invalid? That is, there is no way to store the data and retry later asynchronously (i.e. without locking up the app), since the database is unavailable. Is the assumption that if I just retry a few times, I'll get a valid driver?
UPDATE
Thanks to EJP for correctly pointing out that jdbcDriver is a class in my code. That is correct -- it is a class in a code base I am working on. EJP requests to have the relevant details posted. Here they are.
package us.mydev.jdbc.util;
import java.sql.*;
import javax.naming.*;
import javax.sql.*;
import org.apache.log4j.Logger;
import us.mydev.data.exception.UncheckedSqlException;
public class jdbcDriver
{
[.....]
public jdbcDriver()
{
try
{
m_iActiveConnections++;
if (showLogMessages)
{
log.debug("jdbcDriver() created, hashcode = " + this.hashCode()
+ ",Active Connection Count is " + m_iActiveConnections);
log.debug("Data Source is " + DS_STANDARDUSER);
}
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(DS_STANDARDUSER);
mydevGetJDBCConn getConn = new sqlConn(ds);
m_conn = getConn.getConnection();
m_iDatabaseType = getConn.getDBType();
}
catch (NamingException _exp)
{ // handle any errors
log.error("failed", _exp);
}
}
public boolean isValid() throws SQLException
{
return m_conn != null && m_conn.isValid(10);
}
[.....]
}
I am finding that after this code:
jdbcDriver driver = new jdbcDriver();
boolean driverIsValid = driver.isValid();
...driverIsValid is false about once in every 1000 or so database accesses. I would imagine that this is an artifact of my current dev system -- I have Oracle running in a virtual machine.
Would it be unusual (or unheard of) for driverIsValid to be false in production in a situation like this? And if it is not unheard-of -- how is it usually handled, given that I can't save the relevant data to the database -- that is, can I just retry getting a database connection a few times and expect to get one?
UPDATE #2
Based on what I've learned from the responses, I need to ask this question using no code from the objects defined in the code base I am working on. I'm going to accept the answer provided by Wen-Bin Luo and re-ask the question more properly.
I think you are meaning if a connection is still valid at time of checking. The isValid method returns whether or not a connection is usable. This method can be invoked at any time you like and allows you to set a timeout.
According to the official manual, the method is
particularly useful in combination with a retry mechanism.
helpful when used in conjunction with the connection timeout and connection harvesting features.
You of course can retry the method in the hope of the database issue resolves afterwards, but more generally you set a timeout and after that you may have to take appropriate action and close the connection.
try { conn = poolDataSouorce.getConnection ... } catch (SQLException sqlexc)
{
if (conn == null || !((ValidConnection) conn).isValid())
// take the appropriate action
conn.close
}
For more information, please check https://docs.oracle.com/cd/B28359_01/java.111/e10788/connect.htm#CHDIDEEB
I know there are some topics discussed this matter before but I tried almost all of the solutions with no luck, and I know some don't recommend using JDBC for dealing with DB in android but as for the purpose of my university project I need to use it.
I have a DB hosted by Hostgator and I'm sure of the information I'm using (Host name, user & pass) as I tried them with other Java IDE and they worked perfectly, so no my pc in not blocked either. I added the Mysql J connector to Android Studio as library, tried 2 versions the latest one and 3.0.17, but there's no luck, I don't know what I'm doing wrong as there's no errors or exceptions appearers in the logcat.
this is the code contain the connection to DB: (P.S.I removed exceptions statements to shorten the code)
protected Void doInBackground(Void... params) {
Connection start;
// tried localhost it didn't work
String url = "jdbc:mysql://xxx.xxx.xxx.xxx:3306/abed_impresent";
String username = "abed_bayoun";
String pass = "xxxxx";
Class.forName("com.mysql.jdbc.Driver").newInstance();
start = DriverManager.getConnection(url, username, pass);
Statement my;
if (start != null) {
test = new ArrayList<>();
my = start.createStatement();
ResultSet res = my.executeQuery("select code from Tutors");
while (res.next()) {
test.add(res.getString("code"));
}
for (int c = 0; test.size() > c; c++) {
if (text.getText().equals(test.get(c))) {
Intent i = new Intent(tStart.this, tChoose.class);
startActivity(i);
Toast.makeText(tStart.this, "test", Toast.LENGTH_LONG).show();
break;
} else continue;
}
}
return null;
all codes under if statement is begin skipped, as it seems the app can't connect to DB.
It is highly not recommended to use jdbc driver on android (as far I can remember ony one jdbc version works with android). Instead of jdbc driver consider creating web service which provides content from your database.
Ok I know what I was doing wrong,
I putted this code in a separate try-catch statement
start = DriverManager.getConnection(url, username, pass);
which is somehow blocked the other codes from getting the value of start and deal with it as a null value.
I included the rest of the code in the same try-catch statement and that did the trick for me.
Thanks everybody for your efforts.
Im struggeling with the gae filesystem restrictions.
I am creating a tool that can export a datastructur into a lot of different output-files (json, xml...)
One of them is a sqlite-database-file.
Do you have any ideas how this can be done in this restricted environment?
I tried creating an inmemory database without success:
DriverManager.getConnection("jdbc:sqlite::memory:");
I also tried to use the file-storage bucket:
DriverManager.getConnection("jdbc:sqlite:gs://"+bucketnameü+"/sqllite");
Neither of them worked. I'm afraid this is not possible at all :( I dont want to start a compute engine instance in order to create a sqllite file.
Are there any other frameworks out there that could possible create that database file on the fly.
Here the whole code:
Connection c = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:gs://"+bucketnameü+"/sqllite");
Statement statement = c.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("create table person (id integer, name string)");
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
e.printStackTrace(System.out);
}
I already found an interesting approach in Google AppEngine: Use SQLite file uploaded by user
I tried SQLJet with an inmemory database without success. gaevfs does not look like a good idea either.
If you still need to access the file system you can create a Managed VMs which let you avoid much of App Engine's limitations, particularly the access to the file system.
I'm a junior java programmer and I've finally made my first program, all by myself, apart from school :).
The basics are: you can store data on it and retrieve it anytime. The main thing is, I want to be able to run this program on another computer (as a runable .jar file).
Therefore I had to install JRE and microsoft access 2010 drivers (they both are 32 bit), and the program works perfect, but there is 1 small problem.
It takes ages (literaly, 17 seconds) to store or delete something from the database.
What is the cause of this? Can I change it?
Edit:
Here's the code to insert an object of the class Woord into the database.
public static void ToevoegenWoord(Woord woord) {
try (Connection conn = DriverManager.getConnection("jdbc:odbc:DatabaseSenne")) {
PreparedStatement addWoord =
conn.prepareStatement("INSERT INTO Woorden VALUES (?)");
addWoord.setString(1, woord.getWoord());
addWoord.executeUpdate();
} catch (SQLException ex) {
for (Throwable t : ex) {
System.out.println("Het woord kond niet worden toegevoegd aan de databank.");
t.printStackTrace();
}
}
}
Most likely creating Connection every time is slow operation in your case (especially using JDBC-ODBC bridge). To confirm this try to put print statements with timestamp before and after the line that get Connection from DriverManager. If that's the case consider not to open connection on every request but open it once and reuse, better yet use some sort of Connection Pooling, there are plenty of options available.
If that's mot the case then actual insert could be slow as well. Again simple profiling with print statements should help you to discover where your code is spending most of the time.
First of all, congrats on your first independent foray. To answer your question / elaborate on maximdim's answer, the concern is that calling:
try (Connection conn = DriverManager.getConnection("jdbc:odbc:DatabaseSenne")) {
every time you're using this function may be a major bottleneck (or perhaps another section of your code is.) Most importantly, you will want to understand the concept of using logging or even standard print statements to help diagnose where you are seeing an issue. Wrapping individual lines of code like so:
System.out.println("Before Connection retrieval: " + new Date().getTime());
try (Connection conn = DriverManager.getConnection("jdbc:odbc:DatabaseSenne")) {
System.out.println("AFTER Connection retrieval: " + new Date().getTime());
...to see how many milliseconds pass for each call can help you determine exactly where your bottleneck lies.
Advise: use another database, like Derby, hsqldb. They are not so different from MSAccess, (= can use a file based DB), but perform better (than JDBC/ODBC). And can even be embedded in the application (without extra installation of the DB).
We have a project that uses HP Quality Center and one of the regular issues we face is people not updating comments on the defect.
So I was thinkingif we could come up with a small script or tool that could be used to periodically throw up a reminder and force the user to update the comments.
I came across the Open Test Architecture API and was wondering if there are any good Python or java examples for the same that I could see.
Thanks
Hari
Example of using Python (win32com) to connect to HP Quality Center via OTA
HP Quality Center exposes a com based API called OTA.
Documentation on this is downloadable from an QC server
(OTA_API_Reference.chm) (Weirdly it is very hard to find online)
The documentation uses VBScript (The officially supported internal language for QC)
and you will need to mentally translate to Python. THis is usually very simple, but
a couple of gotchas exist.
You will need to install on your machine the Quality Center local code, this is on your windows PC
if you have been able to get to QC through the web interface.
You will also need to know the URL of the server and you username and password and the domain
of the QC project you are working on.
from win32com.client import Dispatch
conn = get_QCConnection()
for bug in get_bugs(qcConn):
print bug.Title
put_QCConnection(conn)
#below code needs to be in seperate module or at least above the fold but here
# for clarity
def get_QCConnection():
'''Get the hardcoded connection to the server and domain.
Can be made a "real" engine if you try hard.
Use makepy utility to determine if the version number has changed (TDApiOle80)
but this works to current version'''
QCConnection = Dispatch("TDApiOle80.TDConnection")
url = "http://qc.example.com/qcbin"
QCConnection.InitConnectionEx(url)
QCConnection.login("USER", "PASS")
QCConnection.Connect("google_projects", "Google_Chrome")
return QCConnection
def put_QCConnection(qcConn):
#If one person logged in to QC changes *anything* on a bug,
# they hold a global lock on writing to that bug till
# thier session times out, so really really remember to logout
# its painful to wait for your own session to time out
qcConn.Logout()
def get_bugs(qcConn):
'''just following boiler plate from vbscript
PS the SetFilter is not in QTA API, it uses Filter.
But due to the workarounds in
the very brilliant pythoncom code it supplies a virtual wrapper class
called SetFilter - this is one of those gotchas '''
BugFactory = qcConn.BugFactory
BugFilter = BugFactory.Filter
BugFilter.SetFilter(u"Status", "New")
#NB - a lot of fields in QC are malleable - and vary from site to site.
#COntact your admins for a real list of fields you can adjust
buglist = BugFilter.NewList()
return buglist
This is not a bad basis for going forward, however I create a dummy class for defects and run something like:
dfcts = [defect(b) for b in buglist]
Then I can put worker code into defect class and keep things neater.
One thing you want to do is keep access to the raw qc bug internal to the python wrapper class.
Information for others who may view this thread.
To start all this You will need install pywin32, like from here http://sourceforge.net/projects/pywin32/files/pywin32/Build216/
First of all You will need to import pywin32
'''#author: www.qcintegration.com #mailto:contact#qcintegration.com'''
import pywintypes
import win32com.client as w32c
from win32com.client import gencache, DispatchWithEvents, constants
Then as second operation I include here action on login to server
def connect_server(qc, server):
'''Connect to QC server
input = str(http adress)
output = bool(connected) TRUE/FALSE '''
try:
qc.InitConnectionEx(server);
except:
text = "Unable connect to Quality Center database: '%s'"%(server);
return qc.Connected;
def connect_login(qc, username, password):
'''Login to QC server
input = str(UserName), str(Password)
output = bool(Logged) TRUE/FALSE '''
try:
qc.Login(username, password);
except pywintypes.com_error, err:
text = unicode(err[2][2]);
return qc.LoggedIn;
def connect_project(qc, domainname, projectname):
'''Connect to Project in QC server
input = str(DomainName), str(ProjectName)
output = bool(ProjectConnected) TRUE/FALSE '''
try:
qc.Connect(domainname, projectname)
except pywintypes.com_error, err:
text = "Repository of project '%s' in domain '%s' doesn't exist or is not accessible. Please contact your Site Administrator"%(projectname, domainname);
return qc.ProjectConnected;
Second of all method which will include OTAapi dll file
def qc_instance():
'''Create QualityServer instance under variable qc
input = None
output = bool(True/False)'''
qc= None;
try:
qc = w32c.Dispatch("TDApiole80.TDConnection");
text = "DLL QualityCenter file correctly Dispatched"
return True, qc;
except:
return False, qc;
Then main method to connect to QCserver
def qcConnect(server, username, password, domainname, projectname):
print("Getting QC running files");
status, qc = qc_instance();
if status:
print("Connecting to QC server");
if connect_server(qc, server):
##connected to server
print("Checking username and password");
if connect_login(qc, username, password):
print("Connecting to QC domain and project");
if connect_project(qc, domainname, projectname):
text = "Connected"
connected = True;
return connected, text;
else:
text = "Not connected to Project in QC server.\nPlease, correct DomainName and/or ProjectName";
connected = False;
return connected, text;
else:
text = "Not logged to QC server.\nPlease, correct UserName and/or Password";
connected = False;
return connected, text;
else:
text = "Not connected to QC server.\nPlease, correct server http address";
connected = False;
return connected, text;
else:
connected = False;
text = "Unable to find QualityCenter installation files.\nPlease connect first to QualityCenter by web page to install needed files"
return connected, text;
And at the end how to execute all of those methods in one place with example of use
if __name__ == "__main__":
server= r"http://qualitycenterServer:8080/qcbin"
username= "alex_qc"
password= ""
domainname= "DEFAULT"
projectname= "QualityCenter_Demo"
connection_status, text = qcConnect(server, username, password, domainname, projectname);
print "connection_status:", connection_status
In case of any more question mailto: contact#qcintegration.com
or directly to web side: http://www.qcintegration.com
I'm not sure there are any good samples for Java, because OTA can't be consumed by Java directly, it needs a Java to COM bridnge like JIntegra.
About Python, well you can use Python COM api's. And then any OTA example will do. You got plenty in QC documentation of OTA.
But I think the real question here is, why would you want to do it in Python or Java. Why not write what you need directly in QC using it's Workflow feature. Which will allow you to write your logic in VBScript, and have it invoked inside QC UI on user actions. For instance you can bind to the Post event of a Defect / Bug and check if there is a comment and if there is not prompt the user directly with a message.
There is a REST API to HPQC (ALM11 and newer) if you want to access it from Linux without running a Windows COM component.
Here is an example that pulls in a "requirement" record (# 1202) after authenticating.
import requests
session = requests.session()
user='hpqc'
password='xxxxx'
r = session.get("http://hpqc-server:8080/qcbin/authentication-point/authenticate",auth=(user,password))
r = session.get("http://hpqc-server:8080/qcbin/rest/domains/Foo/projects/Bar/requirements/1202")
print(r.text)
The parsing of r.text from XML is left as an exercise.
Though you have asked for a Python or Java based solution, sharing the following VBA code that you can use insde HPQC/ALM's script editor (Defects module script) to accomplish the goal.
Function Bug_FieldCanChange(FieldName, NewValue)
On Error Resume Next
if not changed then
strCommentBeforeUpdate = Bug_Fields("BG_DEV_COMMENTS").Value
end if
If FieldName = "BG_DEV_COMMENTS" and blnAddCommentClicked = False Then
Msgbox "Cannot update the comments." & Chr(13)& "Changes made will not be saved."&Chr(13)& "Please use 'Add comment' button to insert new comment." &Chr(13)& " Or click Cancel without saving."
blnUpdateCommentError = true
blnAddCommentClicked = False
changed = true
End If
Bug_FieldCanChange = DefaultRes
End Function
You can use a new Test and select type (VPXP_API) which allow script to run. The good thing there is that you'd have the function definition ready to be dragged from within QC instead of having to heavily rely on doc.
I've done an implementation in Python running some script from within QC still using its API but via a QC test which is handy to retrieve directly the result (Output) etc.. going through some shell command which can then call any script on any server etc...