For a college assignment I need to write a SAX parser and a filter that reads the original XML file then creates a new modified one. The assignment requires that my program need to be run by console with "java Sax inputFileDestination OutputFileDestination" and it requires that there is only one file. I means I need to implement the interfaces with in the Sax.java. I am familiar with the inner classes but I dont know how to implement this with a main method in the outer class.
Any sugestions?
Since this is an assignment, I'm not going to post any code, but explain how to do it.
I don't think you need an inner class at all to do this. Your class will have a main method, which creates a SAXParser, and registers itself (this) as a callback. You will then implement the SAX methods you desire (startElement, endElement, characters) from HandlerBase.
All your're doing is writing a SAXParser, and then tacking a main() method on it, so it will run from the command line.
Consider creating a MySAXParser class with a usage outside in another class having a main. Then place that main method inside your MySAXParser class as test code.
XML Parsers deliver a jar with a META-INF/MANIFEST.MF using the SPI (Service Provider Interface). You might think of doing the same thing as a bonus.
Other inner classes can be private static if they are independent, or just private storing an extra outer MySAXParser.this; so one error often made is forgetting static.
Related
Is there any way to write a loaded Java object into a .class file or is there any other type of file that can easily be read to represent an instance's properties.
For example, CGLIB will create an proxy bean which extends another, i really want to export this enhanced bean out to a file to see how it was enhanced.
to use HSDB tool in JDK
keep your program running
run HSDB tool:
java -classpath "$JAVA_HOME/lib/sa-jdi.jar" sun.jvm.hotspot.HSDB
input the program pid
choose tools and you can save .class file,that is what you want
For cglib, instances can only be serialized and only if the instance's method interceptors support serialization. There is no other way.
In order to get hold of a cglib-generated class file, you can call the
void generateClass(ClassVisitor v)
method. This method can take an ASM ClassWriter which can after calling the method emitt a byte array representing the class file. This class file by itself does however not help you much as cglib needs to initialize the class explicitly, e.g. inject the callback handlers into the class's fields. This is done inside of the library. However, with the class file at hand and with debug-mode introspection, you can add the pieces and understand how your enhanced class works.
Finally, if I can recommend you an alternative to cglib where all this is easier, have a look at Byte Buddy which has a straight-foward API for extracting a class file and also offers so-called LoadedTypeInitializers in parallel to this class file. The latter initializers contain any setup logic for a class and are easy to read. Also, they are themselfs serializable.
I am making some modifications to already existing code and what I need to do is call a method from class A of project X into a method of class B of project Y, without explicitly importing the class A into class B. Creating an import of class A in class B will create a cycle in the build path, which I have to avoid at all costs. Can anyone help?
Have a look at Dependency Inversion which is basically a principle/technique to manage the directionality of dependencies by using abstract classes or interfaces along with your concrete implementations:
Here's a beginner's tutorial (the examples are in C# but Java doesn't differ much)
You can solve that by an Interface (to call the method), a factory pattern to create the object which method you want to call, and or Reflection which allows to create objects and call methods for which you only know the name (e,g given in an config file).
However try it first without reflection.
I have a large data set. I am creating a system which allows users to submit java source files, which will then be applied to the data set. To be more specific, each submitted java source file must contain a static method with a specific name, let's say toBeInvoked(). toBeInvoked will take a row of the data set as an array parameter. I want to call the toBeInvoked method of each submitted source file on each row in the data set. I also need to implement security measures (so toBeInvoked() can't do I/O, can't call exit, etc.).
Currently, my implementation is this: I have a list of the names of the java source files. For each file, I create an instance of the custom secure ClassLoader which I coded, which compiles the source file and returns the compiled class. I use reflection to extract the static method toBeInvoked() (e.g. method = c.getMethod("toBeInvoked", double[].class)). Then, I iterate over the rows of the data set, and invoke the method on each row.
There are at least two problems with my approach:
it appears to be painfully slow (I've heard reflection tends to be slow)
the code is more complicated than I would like
Is there a better way to accomplish what I am trying to do?
There is no significantly better approach given the constraints that you have set yourself.
For what it is worth, what makes this "painfully slow" is compiling the source files to class files and loading them. That is many orders of magnitude slower than the use of reflection to call the methods.
(Use of a common interface rather than static methods is not going to make a measurable difference to speed, and the reduction in complexity is relatively small.)
If you really want to simplify this and speed it up, change your architecture so that the code is provided as a JAR file containing all of the compiled classes.
Assuming your #toBeInvoked() could be defined in an interface rather than being static (it should be!), you could just load the class and cast it to the interface:
Class<? extends YourInterface> c = Class.forName("name", true, classLoader).asSubclass(YourInterface.class);
YourInterface i = c.newInstance();
Afterwards invoke #toBeInvoked() directly.
Also have a look into java.util.ServiceLoader, which could be helpful for finding the right class to load in case you have more than one source file.
Personally, I would use an interface. This will allow you to have multiple instance with their own state (useful for multi-threading) but more importantly you can use an interface, first to define which methods must be implemented but also to call the methods.
Reflection is slow but this is only relative to other options such as a direct method call. If you are scanning a large data set, the fact you have to pulling data from main memory is likely to be much more expensive.
I would suggest following steps for your problem.
To check if the method contains any unwanted code, you need to have a check script which can do these checks at upload time.
Create an Interface having a method toBeInvoked() (not a static method).
All the classes which are uploaded must implement this interface and add the logic inside this method.
you can have your custom class loader scan a particular folder for new classes being added and load them accordingly.
When a file is uploaded and successfully validated, you can compile and copy the class file to the folder which class loader scans.
You processor class can lookup for new files and then call toBeInvoked() method on loaded class when required.
Hope this help. (Note that i have used a similar mechanism to load dynamically workflow step classes in Workflow Engine tool which was developed).
I am building a webcrawler which is using two classes: a downloader class and an analyzer class. Due to my design of the program I had some methods which I outsourced to a static class named utils (finding the link suffix, determining if I should download it given some variables, etc.). Since at a certain time there is more than one downloader and more than one analyzer I'm wondering whether they can get a wrong answer from some static method in the utils class.
For example, say the analyzer needs to know the link suffix - it's using the utils.getSuffix(link) method. At that same time the OS switches to some downloader thread which also needs to get some link suffix and again uses utils.getSuffix(link). Now the OS switches back to the analyzer thread which does not get the correct response.
Am I right?
In case I'm right should I add synchronized to every method on the utils class? Or should I just use the relevant methods in every thread to prevent that kind of scenario even though I'm duplicating code?
This entirely depends on the implementation of the method. If the method uses only local variables and determines the suffix based on the parameter you give it, all is well. As soon as it needs any resource that is accessible from another thread (local variables and parameters are not) you'll need to worry about synchronization.
It seems to me you're using statics as utilities that don't need anything outside their own parameters; so you should be safe :)
OK, so before we start let me state that I have been googling and searching for an answer to my question for quite a while now and haven't been able to find a suitable one (the keywords are tricky since I keep getting unrelated posts and sites as results).
Now, moving on I have a Java class that contains a my main method and a number of other functions. I want to test these functions using JUnit but I can't instantiate a class that has main in it, if I simply try to call the function I get an error saying the function is outside the namespace even though both files are in the same package, and I get an error trying to import the file.
Is there anyway to test these functions using JUnit?
P.S. Yes I know that you can put them in a new class, but I don't think it is overkill to create a new class just for testing or to put in 2 functions that are for parsing user input, and there is still the issue of testing the main function itself (and it is not uncommon to write a main method just for testing).
So this is what happened. Since I don't use Java very often I ended up creating private data members in the class but treated them as I would globals in a C++ program. In consequence I initialized them in main and didn't think of making a constructor and hence the problem with instantiating the class. When that didn't work I tried the . form but since the methods referenced the private data members I would get an error without instantiating the class. Thanks to the guys that noticed the constructor thing.
You absolutely can create an instance of a class which contains a main method, so long as it has an accessible constructor of course.
Likewise you absolutely can call a static method directly, using MyClassName.myMethodName.
Having a main method in a class makes absolutely no difference to it in terms of the Java language itself - so you can test it just as you would any other class.
Very strange. I just wrote SomeClass with main inside and it's perfectly testable by SomeClassTest class.
Just a thought, did you declare constructors as private in the class with main method? It will help a lot if you can post some code snippet and exact error message you're getting.