Writting a ClassLoader
I'm trying to write a ClassLoader that, when trying to load a class, looks for it in a special directory if the normal way doesn't find it.
I've overriden the findClass method to do the job. It is supposed that the findClass method will call it if the parent classloaders could not load the class.
The I have write a wrapper to instantiate my ClassLoader and ask it to load the main class of any application, using reflection to get the main method.
My problem is this: If the main class of the application is not found in the classpath, the findClass method is called and everything seems to work fine. But if the main class is in the classpath, and other classes are not, my findClass method is never called and I get a NoClassDefFound error.
Does anyone know why the findClass method is not called? Why do I receive a NoClassDefFound error instead of a ClassNotFound exception?
Any clue welcome!
I wrote this somewhere once... some people seemed to find it helpful....
Back to the original question. You want to "unload" a class or set of classes from the VM. Alright, first we have to understand how classes are identified in the VM. A classes "Primary Key" if you will, is its fully qualified name, here it come.... AND a reference to the class loader that loaded it.
So how do we use this information to unload and load some "plugin". Well we know we need to make our own classloader. You can either make your own custom extension, or you can use something like the URL classloader. Next we need to construct this classloader with the current classloader as it's parent. The current classloader might be the bootstrap, or it might be something else (Java Web Start)... This makes using not yet loaded classes in the "normal" classpath possible because the parent will find them. Looking closely we see a problem... If the "plugin" is in the classpath then the parent will just load it. Yeah, it will, so don't put it in the classpath. That's what the URL part of the URLClassloader is for. After all this, we can reflectively load our "plugin" which is located off of the classpath, with our custom classloader.
Now, on to reloading. When a classloader, or class gets GCed has no impact at all on these methods. There could be a gig of classes in memory. If they didn't get loaded by classloader reference I'm holding, I don't care. Here's the idea of the reload. You create a new classloader, and then reflectively invoke the methods and classes you needed all over again. This causes them to be read into the VM again, because their "Primary Key" is different. You need to remember this though, and make sure your using the right classloader to get these classes.
This does work. I have implemented it. I have a piece of software which generates java source code, compiles it, then runs it by a reflective invokation so I can control it. When the user changes something, I re-generate, re-compile, and reload the classes and run the new ones.
enjoy
Similar Messages
-
Is there a way to make my custom ClassLoader the default ClassLoader for my program?
ie. Can I just set up my program to use my ClassLoader whenever it needs to access class files?
Geoff.Hi,
The main class is always loaded by the boot strap class loader(also called System ClassLoader). You can't change it. After that all the classes are loaded by the classloader of the loading class. i.e.
If class A is loading class B, then class B's classloader will be the classloader of class A.
So, basically you need to write a classloader, and a wrapper class for your main class like:
public class WrapperClass
public void main(String[] args) throws Exception
MyClassLoader myClassLoader = new MyClassLoader();
Class mainClass = myClassLoader.loadClass("MainClass");
Method mainMethod = mainClass.getMethod("main", new Class[] {args.getClass()});
mainMethod.invoke(null, args);
}then rest of the classes including MainClass are loaded by the MyClassLoader. If you need help you writing ClassLoader please reply back.
Hope this helps. -
Get All the implementors in a package
Hi
does anybody knows how to obtain all the implementers of an interface in a specific package in an array or List?
same for all extenders
thanksno reliable way, no. since java loads classes lazily, that is, only when another class needs to use them, you've got no way of seeing every class on the classpath
you could write a classloader that iterates over an entire classpath, explicitly loading everything, and do the checking then -
JNI Calling Java code when attaching to existing JVM
I've got an Active/X that runs within IE, and also makes JNI calls (via the Invocation API) to Java code. Running within IE means there's already a JVM around, so I attach to it using JNI_GetCreatedJavaVMs
This is fine. The problem is that I can't use the JNI findClass() to locate my Java classes, because I have no control over the classpath that the JVM is using to locate classes. The only solution I can think of so far is to either add my classes as part of the JVM, OR find out the classpath of the existing JVM (using System.getProperty("java.class.path") and copy my classes into that directory.
Both solutions look ugly - anyone know of a cleaner way ?
Mark.Toby, thanks for the reply.
You're welcome.
I notice from elsewhere on this forum, you're clearly a JNI expert.
I've been known to work with it a little from time to time. =)
My code has to work with JDK 1.1 so URLClassLoader is out. Writing my own classloader is fine, but how do I load it in the first place ? Is there something in JNI I've missed ?
Possibly. Using DefineClass() you can load a class into the virtual machine, given it's byte-code. Now here's the tricky part. First, write your ClassLoader. It will be easiest if it doesn't rely on any other classes other than what is core to the JRE. Once you compile that classloader, you then need to include the bytecode as a resource in your executable/dll. Then, at runtime, you can load that resource, and use DefineClass to class-load it. Once you've class-loaded it, you can use NewObject, GetMethodID, CallXXXMethod, etc... to do the other class loading you need to do.
Trust me, this really isn't as hard as it might sound.
God bless,
-Toby Reyelts
As always, I recommend you check out the free, open-source JNI toolkit, Jace, at http://jace.reyelts.com/jace. -
Could I ask you guys a stupid question, please?
I have a library as an JAR file. I build my application as another JAR file, which includes that library file.
My manifest file is:
Manifest-Version: 0.1.0
Class-Path: lib/mysql-connector-java-3.0.17-ga-bin.jar
Main-Class: com.myappand the build command:
jar cvfm hello.jar mymanifest -c com -c libThe result hello.jar file built OK. But when I run it, I have to copy library file to the same folder to the app file.
Could you tell me how to load the lib file from hello.jar, instead of the lib file?
Thanks in advance!
Best regards,
Lehoanqam I right in thinking you've put the mysql jar inside your application jar? jars don't work like that, I'm afraid. it is possible to write a classloader that will load classes from within a jar-inside-a-jar, but it gets rather complicated and messy and isn't worth the hassle to be honest, anyway. we go to some lengths to keep our software modular and separate. imagine, for instance, that a bug is exposed in the mysql driver you're using, and a new release is needed to fix it. the dependency is rooted inside your application, so the whole shebang has to be re-packaged and re-deployed, whereas if your dependencies were inside a lib folder, all that would be needed is to drop the new version of the mysql driver into the lib directory. think "don't put all your eggs in one basket"
what you want to do is possible, and there are tools around to do it for you, too, but IMHO it's not worth the effort -
Restart application or reload jar-file(class-files)
hi,
i write an update service for my application!everytime a update is available, the new jar-file(my application) will be downloaded and replace the old, running jar-file! now i want to restart my application to use not a mix of old and new class-files in the vm!
is there any possibility for restarting my java vm or is there another way to "refresh the class-files in the vm"?
thx mseeleHi,
The easiest way is to terminate the jvm (using System.exit), and just have a loop in the script file that starts your application. In that way your application will be restarted when the jvm exits.
To write a classloader of your own is another, but a lot harder way.
/Kaj -
Setting classpath during Runtime
hi,
here's what i want to archive:
i have a directory (not! the starting dir) containing classes
the location of that directory i don't know until runtime
the classes have to be accessible by the Class.forName("class").newInstance(); method
no, i can not write a classloader instead of the forName() <- this is fix
i tried with System.setProperty("java.class.path", newclasspath);
and with a classloader, that loads the classes, before the forName() method is invoked (i hoped forName() would find already loaded classes)
didn't work
i'm deeply thankful for every hintIt's not exactly Pure Java (not at all, really).. But
couldn't you do a:
String myOldClasspath,myNewClasspath;
myOldClasspath =
System.getProperty("java.class.path");
Runtime.getRuntime().exec("SET
CLASSPATH="+myNewClasspath);
// Perform Operations
Runtime.getRuntime().exec("SET
CLASSPATH="+myOldClasspath);Probably not.
First 'set' is a shell command so the program wouldn't run at all. You would need to provide a shell.
Second anytime you use exec() it starts another process space. Anything that happens to the environment in that process only affects that process. So this solution would only work if it was acceptable to have two running java applications. The first sets up the environment and the second does the real work. -
Using JDBC to write a DAT file with delimiters to a database
Hi Everybody
I am new to JDBC and i am trying out some small applications: I downloaded this small program and tried to compile it and and I got the following errors: ( I have MySql installed). I have to set the classpath for the driver. But I am not sure why I am gettting the NullPointerException though)
I will be very gratefull to your help. Thanks a lot..
Loading JDBC Driver -> oracle.jdbc.driver.OracleDriver
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at us.ilango.WriteFileToTable.<init>(WriteFileToTable.java:69)
at us.ilango.WriteFileToTable.main(WriteFileToTable.java:367)
java.lang.NullPointerException
at us.ilango.WriteFileToTable.createTable(WriteFileToTable.java:97)
at us.ilango.WriteFileToTable.main(WriteFileToTable.java:368)
Exception in thread "main"
the Program is as follows:
package us.ilango;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.StringTokenizer;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
* The following class provides an example of how to read a simple text file
* of records and then insert them into a table in a database. A text file
* named Employee.txt will contain employee records to be inserted into the
* following table:
* SQL> desc emp
* Name Null? Type
* EMP_ID NOT NULL NUMBER
* DEPT_ID NUMBER
* NAME NOT NULL VARCHAR2(30)
* DATE_OF_BIRTH NOT NULL DATE
* DATE_OF_HIRE NOT NULL DATE
* MONTHLY_SALARY NOT NULL NUMBER(15,2)
* POSITION NOT NULL VARCHAR2(100)
* EXTENSION NUMBER
* OFFICE_LOCATION VARCHAR2(100)
* NOTE: This example will provide and call a method that creates the EMP
* table. The name of the method is called createTable() and is called
* from the main() method.
public class WriteFileToTable {
final static String driverClass = "oracle.jdbc.driver.OracleDriver";
final static String connectionURL = "jdbc:oracle:thin:@localhost:1521:CUSTDB";
final static String userID = "scott";
final static String userPassword = "tiger";
final static String inputFileName = "Employee.txt";
final static String TABLE_NAME = "EMP";
final static String DELIM = ",";
Connection con = null;
* Construct a WriteFileToTable object. This constructor will create an
* Oracle database connection.
public WriteFileToTable() {
try {
System.out.print(" Loading JDBC Driver -> " + driverClass + "\n");
Class.forName(driverClass).newInstance();
System.out.print(" Connecting to -> " + connectionURL + "\n");
this.con = DriverManager.getConnection(connectionURL, userID, userPassword);
System.out.print(" Connected as -> " + userID + "\n");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
* Method used to create the initial EMP table. Before attempting to create
* the table, this method will first try to drop the table.
public void createTable() {
Statement stmt = null;
try {
stmt = con.createStatement();
System.out.print(" Dropping Table: " + TABLE_NAME + "\n");
stmt.executeUpdate("DROP TABLE " + TABLE_NAME);
System.out.print(" - Dropped Table...\n");
System.out.print(" Closing Statement...\n");
stmt.close();
} catch (SQLException e) {
System.out.print(" - Table " + TABLE_NAME + " did not exist.\n");
try {
stmt = con.createStatement();
System.out.print(" Creating Table: " + TABLE_NAME + "\n");
stmt.executeUpdate("CREATE TABLE emp (" +
" emp_id NUMBER NOT NULL " +
" , dept_id NUMBER " +
" , name VARCHAR2(30) NOT NULL " +
" , date_of_birth DATE NOT NULL " +
" , date_of_hire DATE NOT NULL " +
" , monthly_salary NUMBER(15,2) NOT NULL " +
" , position VARCHAR2(100) NOT NULL " +
" , extension NUMBER " +
" , office_location VARCHAR2(100))");
System.out.print(" - Created Table...\n");
System.out.print(" Closing Statement...\n");
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
* Method used to read records from Employee.txt file then write the records
* to an Oracle table within the database named "EMP".
public void performLoadWrite() {
Statement stmt = null;
int insertResults = 0;
StringTokenizer st = null;
String emp_id;
String dept_id;
String name;
String date_of_birth;
String date_of_hire;
String monthly_salary;
String position;
String extension;
String office_location;
try {
System.out.print(" Creating Statement...\n");
stmt = con.createStatement ();
System.out.print(" Create FileReader Object for file: " + inputFileName + "...\n");
FileReader inputFileReader = new FileReader(inputFileName);
System.out.print(" Create BufferedReader Object for FileReader Object...\n");
BufferedReader inputStream = new BufferedReader(inputFileReader);
String inLine = null;
while ((inLine = inputStream.readLine()) != null) {
st = new StringTokenizer(inLine, DELIM);
emp_id = st.nextToken();
dept_id = st.nextToken();
name = st.nextToken();
date_of_birth = st.nextToken();
date_of_hire = st.nextToken();
monthly_salary = st.nextToken();
position = st.nextToken();
extension = st.nextToken();
office_location = st.nextToken();
System.out.print(" Inserting value for [" + name + "]\n");
insertResults = stmt.executeUpdate(
"INSERT INTO " + TABLE_NAME + " VALUES (" +
emp_id +
" , " + dept_id +
" , '" + name + "'" +
" , '" + date_of_birth + "'" +
" , '" + date_of_hire + "'" +
" , " + monthly_salary +
" , '" + position + "'" +
" , " + extension +
" , '" + office_location + "')");
System.out.print(" " + insertResults + " row created.\n");
System.out.print(" Commiting Transaction...\n");
con.commit();
System.out.print(" Closing inputString...\n");
inputStream.close();
System.out.print(" Closing Statement...\n");
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
* Method used to query records from the database table EMP. This method
* can be used to verify all records have been correctly loaded from the
* example text file "Employee.txt".
public void queryRecords() {
Statement stmt = null;
ResultSet rset = null;
int deleteResults = 0;
int rowNumber = 0;
int emp_id;
int dept_id;
String name;
String date_of_birth;
Date date_of_birth_p;
String date_of_hire;
Date date_of_hire_p;
float monthly_salary;
String position;
int extension;
String office_location;
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
NumberFormat defaultFormat = NumberFormat.getCurrencyInstance();
System.out.print(" Creating Statement...\n");
stmt = con.createStatement ();
System.out.print(" Opening query for table: " + TABLE_NAME + "...\n");
rset = stmt.executeQuery ("SELECT * FROM emp ORDER BY emp_id");
while (rset.next ()) {
rowNumber = rset.getRow();
emp_id = rset.getInt(1);
if ( rset.wasNull() ) {emp_id = -1;}
dept_id = rset.getInt(2);
if ( rset.wasNull() ) {dept_id = -1;}
name = rset.getString(3);
if ( rset.wasNull() ) {name = "<null>";}
date_of_birth = rset.getString(4);
if ( rset.wasNull() ) {date_of_birth = "1900-01-01";}
try {
date_of_birth_p = formatter.parse(date_of_birth);
} catch (ParseException e) {
date_of_birth_p = new Date(0);
date_of_hire = rset.getString(5);
if ( rset.wasNull() ) {date_of_hire = "1900-01-01";}
try {
date_of_hire_p = formatter.parse(date_of_hire);
} catch (ParseException e) {
date_of_hire_p = new Date(0);
monthly_salary = rset.getFloat(6);
if ( rset.wasNull() ) {monthly_salary = 0;}
position = rset.getString(7);
if ( rset.wasNull() ) {position = "<null>";}
extension = rset.getInt(8);
if ( rset.wasNull() ) {extension = -1;}
office_location = rset.getString(9);
if ( rset.wasNull() ) {office_location = "<null>";}
System.out.print(
"\n" +
" RESULTS -> [R" + rowNumber + "] " + "\n" +
" Employee ID : " + emp_id + "\n" +
" Department ID : " + dept_id + "\n" +
" Employee Name : " + name + "\n" +
" D.O.B. : " + date_of_birth_p + "\n" +
" Date of Hire : " + date_of_hire_p + "\n" +
" Monthly Salary : " + defaultFormat.format(monthly_salary) + "\n" +
" Position : " + position + "\n" +
" Extension : x" + extension + "\n" +
" Office Location : " + office_location +
"\n");
System.out.print(" Closing ResultSet...\n");
rset.close();
System.out.print(" Closing Statement...\n");
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
* Close down Oracle connection.
public void closeConnection() {
try {
System.out.print(" Closing Connection...\n");
con.close();
} catch (SQLException e) {
e.printStackTrace();
* Sole entry point to the class and application.
* @param args Array of String arguments.
* @exception java.lang.InterruptedException
* Thrown from the Thread class.
public static void main(String[] args)
throws java.lang.InterruptedException {
WriteFileToTable runExample = new WriteFileToTable();
runExample.createTable();
runExample.performLoadWrite();
runExample.queryRecords();
runExample.closeConnection();
}Hi
Thanks a lot. I ran the program with the MySql driver as follows:
The errors are as follows: I will ttry to place the Driver in the Classpath. As far as I know the driver has been specified correctly this time.
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at us.ilango.WriteAntennas.<init>(WriteAntennas.java:41)
at us.ilango.WriteAntennas.main(WriteAntennas.java:377)
java.lang.NullPointerException
at us.ilango.WriteAntennas.createTable(WriteAntennas.java:70)
at us.ilango.WriteAntennas.main(WriteAntennas.java:378)
Exception in thread "main" Loading JDBC Driver -> com.mysql.jdbc.Driver
The program is as follows:
package us.ilango;
* @author ilango
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.StringTokenizer;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class WriteAntennas {
final static String driverClass = "com.mysql.jdbc.Driver";
final static String connectionURL = "jdbc:mysql://localhost/test2";
final static String userID = "brian";
final static String userPassword = " ";
final static String inputFileName = "CO.DAT";
final static String TABLE_NAME = "CELL";
final static String DELIM = "|";
Connection con = null;
public WriteAntennas() {
try {
System.out.print(" Loading JDBC Driver -> " + driverClass + "\n");
Class.forName(driverClass).newInstance();
System.out.print(" Connecting to -> " + connectionURL + "\n");
this.con = DriverManager.getConnection(connectionURL, userID, userPassword);
System.out.print(" Connected as -> " + userID + "\n");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
* Method used to create the initial EMP table. Before attempting to create
* the table, this method will first try to drop the table.
public void createTable() {
Statement stmt=null;
try {
stmt = con.createStatement();
System.out.print(" Dropping Table: " + TABLE_NAME + "\n");
stmt.executeUpdate("DROP TABLE " + TABLE_NAME);
System.out.print(" - Dropped Table...\n");
System.out.print(" Closing Statement...\n");
stmt.close();
} catch (SQLException e) {
System.out.print(" - Table " + TABLE_NAME + " did not exist.\n");
try {
stmt = con.createStatement();
System.out.print(" Creating Table: " + TABLE_NAME + "\n");
stmt.executeUpdate("create table TOWER_PUBACC_CO (" +
"record_type char(2) null" +
", content_indicator char(3) null" +
", file_number char(8) null" +
", registration_number char(7) null" +
", unique_system_identifier long(9,0) not null" +
", coordinate_type char(1) not null" +
",latitude_degrees int null" +
",latitude_minutes int null" +
",latitude_seconds int(4,1) null" +
",latitude_direction char(1) null" +
",latitude_total_seconds int(8,1) null" +
",longitude_degrees int null" +
",longitude_minutes int null" +
",longitude_seconds int(4,1) null" +
",longitude_direction char(1) null" +
",longitude_total_seconds int(8,1) null)" );
System.out.print(" created Table...\n");
System.out.print(" closing Statement...\n");
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
public void performLoadWrite() {
Statement stmt = null;
int insertResults = 0;
StringTokenizer st = null;
String record_type ;
String content_indicator;
String file_number ;
String registration_number;
String unique_system_identifier ;
String coordinate_type;
String latitude_degrees;
String latitude_minutes;
String latitude_seconds;
String latitude_direction;
String latitude_total_seconds;
String longitude_degrees;
String longitude_minutes;
String longitude_seconds;
String longitude_direction;
String longitude_total_seconds;
try {
System.out.print(" Creating Statement...\n");
stmt = con.createStatement ();
System.out.print(" Create FileReader Object for file: " + inputFileName + "...\n");
FileReader inputFileReader = new FileReader(inputFileName);
System.out.print(" Create BufferedReader Object for FileReader Object...\n");
BufferedReader inputStream = new BufferedReader(inputFileReader);
String inLine = null;
while ((inLine = inputStream.readLine()) != null) {
st = new StringTokenizer(inLine, DELIM);
record_type = st.nextToken();
content_indicator = st.nextToken();
file_number = st.nextToken();
registration_number = st.nextToken();
unique_system_identifier = st.nextToken();
coordinate_type =st.nextToken();
latitude_degrees = st.nextToken();
latitude_minutes = st.nextToken();
latitude_seconds=st.nextToken();
latitude_direction = st.nextToken();
latitude_total_seconds =st.nextToken();
longitude_degrees= st.nextToken();
longitude_minutes = st.nextToken();
longitude_seconds = st.nextToken();
longitude_direction=st.nextToken();
longitude_total_seconds =st.nextToken();
System.out.print(" Inserting value for [" + unique_system_identifier + "]\n");
insertResults = stmt.executeUpdate(
"INSERT INTO " + TABLE_NAME + " VALUES (" +
record_type +
" , " + content_indicator +
" , '" + file_number + "'" +
" , '" + registration_number + "'" +
" , '" + unique_system_identifier + "'" +
" , " + coordinate_type + "'" +
" , '" + latitude_degrees + "'" +
" , " + latitude_minutes + "'" +
" , '" + latitude_seconds + "'" +
" , '" + latitude_direction + "'" +
" , '" + latitude_total_seconds + "'" +
" , '" + longitude_minutes + "'" +
" , '" + longitude_seconds + "'" +
" , '" + longitude_direction + "'" +
" , '" + longitude_total_seconds + "')");
System.out.print(" " + insertResults + " row created.\n");
System.out.print(" Commiting Transaction...\n");
con.commit();
System.out.print(" Closing inputString...\n");
inputStream.close();
System.out.print(" Closing Statement...\n");
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
public void queryRecords() {
Statement stmt = null;
ResultSet rset = null;
int deleteResults = 0;
int rowNumber = 0;
String record_type;
String content_indicator;
String file_number;
String registration_number ;
long unique_system_identifier;
String coordinate_type ;
int latitude_degrees ;
int latitude_minutes ;
int latitude_seconds;
String latitude_direction;
int latitude_total_seconds;
int longitude_degrees;
int longitude_minutes;
int longitude_seconds;
String longitude_direction;
int longitude_total_seconds;
try {
System.out.print(" Creating Statement...\n");
stmt = con.createStatement ();
System.out.print(" Opening query for table: " + TABLE_NAME + "...\n");
rset = stmt.executeQuery ("SELECT * FROM cell ORDER BY unique_system_identifier");
while (rset.next ()) {
rowNumber = rset.getRow();
unique_system_identifier = rset.getInt (1);
if ( rset.wasNull() ) {unique_system_identifier = -1;}
record_type = rset.getString (2);
if ( rset.wasNull() ) {record_type = "<null>";}
content_indicator = rset.getString(3);
if ( rset.wasNull() ) {content_indicator = "<null>";}
file_number = rset.getString(4);
if ( rset.wasNull() ) {file_number = "<null>";}
registration_number = rset.getString(5);
if ( rset.wasNull() ) {registration_number = "<null>";}
coordinate_type = rset.getString(6);
if ( rset.wasNull() ) {coordinate_type = "<null>";}
latitude_degrees = rset.getInt(7);
if ( rset.wasNull() ) {latitude_degrees = 1;}
latitude_minutes = rset.getInt(8);
if ( rset.wasNull() ) {latitude_minutes = 1;}
latitude_seconds = rset.getInt(9);
if ( rset.wasNull() ) {latitude_seconds = 1;}
latitude_direction = rset.getString(10);
if ( rset.wasNull() ) {latitude_direction = "<null>";}
latitude_total_seconds = rset.getInt(11);
if ( rset.wasNull() ) {latitude_total_seconds = 1;}
longitude_degrees = rset.getInt(12);
if ( rset.wasNull() ) {longitude_degrees = 1;}
longitude_minutes = rset.getInt(13);
if ( rset.wasNull() ) {longitude_minutes = 1;}
longitude_seconds = rset.getInt(14);
if ( rset.wasNull() ) {longitude_seconds = 1;}
longitude_direction = rset.getString(15);
if ( rset.wasNull() ) {longitude_direction = "<null>";}
longitude_total_seconds = rset.getInt(16);
if ( rset.wasNull() ) {longitude_total_seconds = 1;}
System.out.print(
"\n" +
" RESULTS -> [R" + rowNumber + "] " + "\n" +
" Unique_System_Identifier : " + unique_system_identifier + "\n" +
" Record_type : " + record_type + "\n" +
" Content_Indicator : " + content_indicator + "\n" +
" Registration_Number : " + registration_number + "\n" +
" File_Number : " + file_number + "\n" +
" Coordinate_Type : " + coordinate_type + "\n" +
" Latitude_Degrees : " + latitude_degrees + "\n" +
" Latitude_Minutes : " + latitude_minutes + "\n" +
" Latitude_Seconds : " + latitude_seconds + "\n" +
" Latitude_Direction : " + latitude_direction + "\n" +
" Latitude_Total_Seconds : " + latitude_total_seconds + "\n" +
" Longitude_Degrees : " + longitude_degrees + "\n" +
" longitude_minutes : " + longitude_minutes + "\n" +
" Longitude_Seconds : " + longitude_seconds + "\n" +
" longitude_direction : " + longitude_direction + "\n" +
" Longitude_Total_Seconds : " + longitude_total_seconds +
"\n");
System.out.print(" Closing ResultSet...\n");
rset.close();
System.out.print(" Closing Statement...\n");
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
public void closeConnection() {
try {
System.out.print(" Closing Connection...\n");
con.close();
} catch (SQLException e) {
e.printStackTrace();
public static void main(String[] args)
throws java.lang.InterruptedException {
WriteAntennas runJob = new WriteAntennas();
runJob.createTable();
runJob.performLoadWrite();
runJob.queryRecords();
runJob.closeConnection();
} -
Loading an entire JAR via a classloader
Hi how would I load an entire JAR file via a classloader. Currently I'm able to load one file at a time (in this case org.w3c.dom.Node) as shown below:
import java.net.*;
public class MyJarLoader {
public static void main(String [] args) throws Exception {
URL[] urlsToLoadFrom = new URL[]{new URL("file:subdir3/xml-apis.jar")};
URLClassLoader loader1 = new URLClassLoader(urlsToLoadFrom);
Class cls1 = Class.forName("org.w3c.dom.Node", true, loader1);
System.out.println("Loaded '"+cls1.getName()+"'");
org.w3c.dom.Node Node = (org.w3c.dom.Node) cls1.newInstance();
ThanksFigured this one out as below. Note this is the simplistic solution since it requires that the jar files be present in the classpath. If not, you will have to write your own loadClass method to read the data from the zip (& then can't use the method 'Class.forName()').
Regards
//Load Apache JAR files
URL[] urlArrToLoadFrom = new URL[]{new URL("file:xalan-j_2_5_0/xml-apis.jar"),
new URL("file:xalan-j_2_5_0/xercesImpl.jar"), new URL("file:xalan-j_2_5_0/xalan.jar")};
//Create a URLClassLoader to access jar files
URLClassLoader urlLoaderGeneric = new URLClassLoader(urlArrToLoadFrom);
//Foreach jar file, open, load class files & close
for(int i=0; i<urlArrToLoadFrom.length; i++) {
//Debug
System.out.println(urlArrToLoadFrom.toString());
//Open zip file
ZipFile zf = new ZipFile(urlArrToLoadFrom[i].getFile());
for (Enumeration enum = zf.entries(); enum.hasMoreElements();) {
//Get entry
ZipEntry ze = (ZipEntry) enum.nextElement();
//Only load if it's not a directory and it's a class file
int iIndexClass = -1;
if (!ze.isDirectory() && ((iIndexClass = ze.getName().indexOf(".class")) != -1)) {
//Remove .class & replace / with .
String strApacheClassName = (ze.getName().substring(0,iIndexClass)).replace('/','.');
//Load class file
Class classApache = Class.forName(strApacheClassName, true, urlLoaderGeneric);
System.out.println("Loaded '"+classApache.getName()+"'");
//Close zip
zf.close(); -
Namespace mapping with classloading
It is proposed that a secure sandbox for applications could be made with mapping loaded classes into secure classes. For example, when a person is using java.io.File, the classloader returns org.my.File, which extends java.io.File. Using this technique, we may have security profiles for different users. For example, some users may use net-package and some may not. The classloader (with help of profiles) will decide what to load for each user.
I have implemented a classloader that initially loads org.my.File-class, and when a loaded application (loaded through this ClassLoader) tries to load java.io.File, the classloader simply returns the previously loaded org.my.File-class.
This results in java.lang.NoClassDefFoundError: java/io/File. Other loading methods that I have tried have ended in ClassCircularityExceptions and Hotspot VM crashes. I am currently using Windows 2000 Pro; Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_03-b02) and Java HotSpot(TM) Client VM (build 1.4.1_03-b02, mixed mode).
Any ideas why this doesn't work? Is it possible to make work? Does someone know an alternative method how to achieve desired behaviour?
Thanks,
Teemu.
public class AClassLoader extends ClassLoader {
private URL[] urls;
private Class fileclass;
public AClassLoader(URL[] list_of_urls ) {
urls = list_of_urls;
try {
fileclass = findSystemClass("org.my.File");
resolveClass(axelfile);
catch (Exception e) {System.out.println(e);}
public Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.indexOf("java.io.File")!=-1) { return classfile; }
Class class_to_load = null;
// check if already loaded
class_to_load = findLoadedClass(name);
// class was found, return it
if (class_to_load!=null) { return class_to_load; }
// this is reached only if class was not found
try {
URL url = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int i=0;i<urls.length;i++) {
// if class is found, do not enter try
if (class_to_load==null) {
String filename = name;
filename = filename.replace('.','/');
url = urls;
filename = url.toString()+filename+".class";
url = new URL(filename);
try {
InputStream is = url.openStream();
// collect bytes to vector
int b = -1;
while ( (b = is.read()) != -1 ) {
baos.write(b);
is.close();
// create bytearray
byte[] byte_array = baos.toByteArray();
// try to define bytearray as a class
class_to_load = defineClass(name, byte_array, 0, byte_array.length);
catch (FileNotFoundException u) { }
catch (Exception u2) { }
} // if
catch (Exception e) { System.out.println(e); }
if (class_to_load==null) {
try {
class_to_load = findSystemClass(name);
return class_to_load;
catch (NoClassDefFoundError e) { }
if (class_to_load==null) { throw new ClassNotFoundException("Class "+name+" was not found from given urls or system."); }
// try to resolve class, if needed
if ((class_to_load!=null)&&(resolve)) {
resolveClass(class_to_load);
return class_to_load;The code I sent in first message is not entirely correct. I clipped it out from my original code and changed variables, but I accidentally left some errors in it...
I have done some tests and I found few errors from my code and some interesting and annoying facts from java class loading behaviour.
It seems now like the system classes, like java.io.File are not added to found classes list after they are loaded with findSystemClass.
If I try to define system class from bytes with defineClass(), it results: "java.lang.SecurityException: Prohibited package name: java.io". After that I have to load that class with findSystemClass().
So, when I am returning org.my.File instead of java.io.File, I get java.lang.NoClassDefFoundError: java/io/File. I believe this results because java.io.File can not be found with findLoadedClass() (java.io.File is not added in to the "known classes" list ?!)
Can someone give me hints how to load own class instead of a system class? How the system class can be loaded so that it can be found with findLoadedClass()? Or am I doing this completely wrong? -
BufferedWriter write = new BufferedWriter(new FileWriter("file100.txt"));
write.write("testttttttttttttttt");
write.close();
File f1 = new File("file100.txt");
System.out.println(f1.exists()); --- this returns true
System.out.println(ClassLoader.getSystemResource("file100.txt").toString()); -- this returns NullPointerException, why??
also
File f = new File("file1.txt");
System.out.println(f.exists()); -- returns false, but file1.txt is in the same directory as file100.txt, the only difference is it wasn't created in the program, it's already there
Please help! thank you!System.out.println(ClassLoader.getSystemResource("file1
0.txt").toString()); -- this returns
NullPointerException, why??The ClassLoader should be used to load java classes to memory, since file100.txt isn't a java class getSystemResource . To read a File use FileReader or FileInputStream.
>
also
File f = new File("file1.txt");
System.out.println(f.exists()); -- returns false,
se, but file1.txt is in the same directory as
file100.txt, the only difference is it wasn't created
in the program, it's already thereIs that the directory the program was started from? That wil most likely be the current directory is you don't specify a path. -
ClassLoader in JAR file not loading config file properly
Hi all,
I have an application that I am going to deploy using JavaWS, and everything works fine except for one little hitch. I have a configuration file, nvacconfig, located at NVAC.jar/config/nvacconfig. I'm trying to load this file into my application using a ClassLoader, but it does not seem to be working.
I have a method from a certain class that loads the configuration file. The class is not important, as it is part of an API that I cannot alter. This class has a load(String file) method, that loads the specified configuration file with a String argument. This works fine when I run my application from the command line and when the configuration file is not located in the JAR, but I need to include this configuration file in my JAR, so I can run my app in the JWS sandbox.
To load the file when it is NOT inside a JAR, and is simply located at config/nvacconfig, I just use:
id.properties.load("config/nvacconfig");and it loads the configuration file, nvacconfig.
When I include the file in my JAR and try to load it using a ClassLoader, it does not seem to work, and the load method cannot find the file. This is how I am trying to accomplish this:
ClassLoader cl = this.getClass().getClassLoader();
URL url = cl.getResource("config/nvacconfig");
String file = url.toString(); //I have also tried String file = url.getFile();
id.properties.load(file);This does not work, and I'm not sure why.
Is there something I am doing wrong? Is this the wrong way to go about this?
Any advice would be greatly appreciated.
Thanks,
Dan
Message was edited by:
Djaunltry this:
import java.io.*;
import java.util.jar.*;
import java.util.zip.*;
public class ExtractFromJAR {
public void extractFileFromJAR(String dest, String fileName) {
try {
String home = getClass().getProtectionDomain().getCodeSource().getLocation().getPath().replaceAll("%20",
JarFile jar = new JarFile(home);
ZipEntry entry = jar.getEntry(fileName);
File efile = new File(dest, entry.getName());
InputStream in = new BufferedInputStream(jar.getInputStream(entry));
OutputStream out = new BufferedOutputStream(new FileOutputStream(efile));
byte[] buffer = new byte[2048];
for (;;) {
int nBytes = in.read(buffer);
if (nBytes <= 0)
break;
out.write(buffer, 0, nBytes);
out.flush();
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
public static void main(String args[]) {
new ExtractFromJAR().extractFileFromJAR(".", "file.txt");
} -
Converting byte[] to Class without using defineClass() in ClassLoader
so as to de-serialize objects that do not have their class definitions loaded yet, i am over-riding resolveClass() in ObjectInputStream .
within resolveClass() i invoke findClass() on a network-based ClassLoader i created .
within findClass() , i invoke
Class remoteClass = defineClass(className, classImage, 0, classImage.length);
and that is where i transform a byte[] into a Class , and then finally return a value for the resolveClass() method.
this seems like a lengthy process. i mean, within resolveClass() i can grab the correct byte[] over the network.
then, if i could only convert this byte[] to a Class within resolveClass() , i would never need to extended ClassLoader and over-ride findClass() .
i assume that the only way to convert a byte[] to a Class is using defineClass() which is hidden deep within ClassLoader ? there is something going on under the hood i am sure. otherwise, why not a method to directly convert byte[] to a Class ? the byte[] representation of a Class always starts with hex CAFEBABE, and then i'm sure there is a standard way to structure the byte[] .
my core issue is:
i am sending objects over an ObjectInputStream created from a Socket .
at the minimum, i can see that resolveClass() within ObjectInputStream must be invoked at least once .
but then after that, since the relevant classes for de-serialization have been gotten over the network, i don't want to cascade all the way down to where i must invoke:
Class remoteClass = defineClass(className, classImage, 0, classImage.length);
again. so, right now, within resolveClass() i am using a Map<String, Class> to create the following class cache:
cache.put(objectStreamClass.getName(), Class);
once loaded, a class should stay loaded (even if its loaded in the run-time), i think? but this is not working. each de-serialization cascades down to defineClass() .
so, i want to short-circuit the need to get the class within the resolveClass() method (ie. invoke defineClass() only once),
but using a Map<String, Class> cache looks really stupid and certainly a hack.
that is the best i can do to explain my issue. if you read this far, thanks.ok. stupid question:
for me to use URLClassLoader , i am going to need to write a bare-bones HTTP server to handle the class requests, right?Wrong. You have to deploy one, but what's wrong with Apache for example? It's free, for a start.
and, i should easily be able to do this using the com.sun.net.httpserver library, right?Why would you bother when free working HTTP servers are already available? -
API access to Java Plug-In "x: clear classloader cache" in Java Console
I am using some third-party tools in a Java application I am developing.
I am encountering an error that can be worked around manually by issuing the subject command at the appropriate time. Is there API access to this functionality, so that I can programatically invoke the workaround?
Thanks in advance for your time and consideration.Well, I finally came to a solution that is acceptable at least to me, if not ideal. I've started using the BouncyCastle lightweight API. This makes my code somewhat more complicated, and I had to bundle up all the BouncyCastle classes that I'm using into a jar file, and download that to my applet along with my client jar file (after signing the jar files). Using this Lightweight API bypasses the Cipher.getInstance() method all together, and is a little harder to use, but at least everything is working consistently now.
I still believe this to be a bug either in the ClassLoader or the Cipher.getInstance() method. I intend to try to write a test applet that reproduces the error in a more simple way and if I can pull that off, I'll submit a bug report to Sun.
Thanks to all who responded!!
Steve -
Given 3 deployed ears within the same weblogic 8.1sp4 server instance we try to pass a result object from ear1 to ear3 via ear2 (ear2 is basically a "heavyweight" facade for ear1).
-Ear1 -> Ear2 --> Ear3
ear2 and ear3 only know the interface implemented by the result object, the object itself gets instantiated in ear1. While unmarshalling and remote classloading of the result object works flawlessly in ear2, passing it on to ear3 causes a ClassNotFound exception in ear3 since the implementing class cannot be found.
Where should the implementing class be loaded from in ear3 or is passing remotely loaded classes over various nodes impossible?
Thanks in advance
/cpAmethastos Lorekeeper <> writes:
Looks like a bug to me, although how we would fix it I'm not sure.
andy
Given 3 deployed ears within the same weblogic 8.1sp4 server instance we try to pass a result object from ear1 to ear3 via ear2 (ear2 is basically a "heavyweight" facade for ear1).
-Ear1 -> Ear2 --> Ear3
ear2 and ear3 only know the interface implemented by the result object, the object itself gets instantiated in ear1. While unmarshalling and remote classloading of the result object works flawlessly in ear2, passing it on to ear3 causes a ClassNotFound exception in ear3 since the implementing class cannot be found.
Where should the implementing class be loaded from in ear3 or is passing remotely loaded classes over various nodes impossible?
Thanks in advance
/cp
Maybe you are looking for
-
Replication issue in ABAP to ABAP scenario
Hello, I have a ABAP to ABAP replication scenario where I am replicating custom and standard tables like MDMA but found below issue. The replication current action is struck in "Replication (Initial Load)" with Initial load is getting done but not re
-
LSMW Employee importing.
Hello, I have the next problem. I use lsmw for employee importing. First of all I exported established posts to the text file, then somebody filled it (inserted first name, last name, middle name, birth date and ***). I imported filled text file to S
-
Satellite P30-145: Don't have an audio device in 'Sounds and Audio devices'
Hi guys, I've only just fixed one problem with the help of one fantastic member but now I have another! All of a sudden my speakers decide not to work!! I checked the volume etc and alll was fine but when I went in control panel>sounds and audio devi
-
How to install servlet classes in order to compile a simple servlet...
When trying to compile a simple servlet (java file), I get errors having to do with not finding any object of the javax.servlet class. I am using J2SE v.1.4, and from what I know, it does not have built-in support for Servlets-JSP. Do I need to insta
-
Kann bei meinem neuen pc nicht mehr zugreifen.