I simply want to implement that line programmatically in runtime.
import com.company.package.*;
I can't believe all the searches lead to Python, and I certainly would prefer not loading classes and looping one by one. It must be a faster command.
Any suggestion?
P.S: I know it's not the best of designs, but I am doing it through a JSP, so perhaps there is some way to use a parameter in the declaration as in
<%# page import=%{myPackage} %>
ClassLoader is too dynamic/flexible to do what you're asking. Specifically, there is no portable way to list the contents of a directory from a ClassLoader, so there is no way to determine the complete set of classes to be loaded. Here are two non-portable suggestions:
Assume your ClassLoader implements URLClassLoader, then call getURLs, then assume the URLs are file: ...or:
Assume ClassLoader.getResource("com/company/package/") will return a non-null URL, then assume the URL will be file: (or jar:, then assume the inner URL is file:, and then extract and use that)
In either case, parse file: URL (handling URL decoding), list the contents of the directory/JAR to find all *.class files.
Note, this is basically what Spring classpath*: does, and they include several portability warnings in their documentation for these reasons.
Related
I want to implement a function that will take package name as input and list all the contents(only files) inside that package.
public List<String> getContents(String packageName) {
...
}
Example input
packageName = com.spring.com.demo
Expexted output
Class1.java
Class2.java
...
What is the best way to accomplish this task?
You're talking about java's 'classloader' system, which is a slight misnomer, in that it can also load resources other than classes. Point is, classes are a resource that are located somewhere, and the JVM itself needs to find them. After all, when you are running your main class and it refers to 'new Foobar()', the jvm needs to find Foobar.class somehow, read the bytes, and turn them into a new class definition.
Java's classloader system is generalized in two ways:
You can call on it to find you stuff.
You can for example write:
MyApp.class.getResource("icons/share.png")
and get a URL object you can pass straight to e.g. ImageIcon. This way, you can ship your icons for your GUI app together with your class files, and it's completely unified: However the system is loading the classes, be it from disk, from inside a jar file, from eclipse's module system if it's an eclipse plugin, or from the network - this way you're loading your images from the same place.
You can make your own
Let's say you want to write a system that loads classes (and other resources, like images) directly from the web. You can do that: You can make your own ClassLoaders.
Now for the crux of the matter
That means ClassLoader is an abstract concept that lists which features it has. It's like any other interface / abstract class in that regard: It's a template that defines what you can do with one, so that anybody can provide you with an implementation of it.
Here's the crucial thing you must understand so that you know why what you want is impossible (and why the commonly called out 'reflections' library is a hack that doesn't universally work):
The ClassLoader abstract simply has no list command.
Hence, listing? Simply not possible. The only command it does have is 'load Resource X', X being some path-like string. That is all it has. The java classloader system is never in need to 'list all classes in a package', not even when there's a star import (which is just a thing javac knows about, at the class file level star imports aren't a thing). The JVM just needs to e.g. load resource '/java/lang/String.class' - hence, the command 'here is a path, please give me the bytes for it' is all that is neccessary.
The solution to have lists anyway
During compilation, the abstractions do support 'list'. After all, the compiler really does just read java files from a directory (which supports 'list all files inside it'), you can't for example tell the compiler 'please compile all .java files in this .jar file). So, at compile time, you can make a list of resources.
So here's the trick: Save that in a text file and ask for the text file during runtime. Then translate each line in the text file to the full resource path and then ask for each of those. Thus, using just the one API call you have available to you at runtime ('load resource at path X'), you can have a list system anyway. It's just that during the compilation/build/packing step you need the tools that compile/build/pack to do some work and make you a text file with the details.
This is called the SPI (Service Provider Interface) system and java itself uses it - it's how JDBC drivers and e.g. charset implementations are found.
You can use this yourself in this three step process:
Define an interface or abstract class that serves as the thing 'providers' will implement/extend. Let's say it is com.ranjan.MyService`.
At the provider end: Write an implementation for it. Let's say it's com.zwitserloot.ServiceImpl.
During compilation, ensure that in the same place the class files end up (e.g. in the jar file for example), there's META-INF/services/com.ranjan.Myservice (a text file). This file contains the fully qualified class name of each 'provider' class: com.zwitserloot.ServiceImpl is what's on the first (and only) line.
At runtime: Use java.util.ServiceLoader and it'll take care of everything.
Your specific use case
From comments it seems like you don't really need to 'list classes', you have a bunch of classes and need to know if they are 'valid', for some definition of 'valid'. You can either just Class.forName them, though this will also initialize them (run its static initializers). Alternatively, you can run YourOwnClass.class.getResource("com.spring.com.demo.Class1.class"), and check that [A] you get an actual resource (and not null, indicating it doesn't exist), and [B] do whatever validation you want to do on this. For example, toss it through bytebuddy or ASM or some other class format editor and check if it can parse it.
I have a multilingual web application that gets all of the translations from a single object, for example lang.getTranslation("Login") and the object is responsible for finding the translation in an xml file in the user's language.
What I'd like to do is a script / custom static analysis that outputs all the missing translations and translations that are no more used in the application. I believe I should start by programmatically finding every call to the getTranslation method and the string parameter, storing the data in a special structure and comparing it to all the translation files.
Is there a library that will allow me to do this easily? I already found Javassist but I can't use it to read the parameter values. I also tried grepping, but I'm not sure if that's a robust solution (in case there will be a call to another class that has a getTranslation method). I know Qt has a similar mechanism for finding translatable strings in the code, but that's a totally different technology..
I'm asking this because I'm quite sure there's a good existing solution for this and I don't want to reinvent the wheel.
Ok, here's how I did it. Not the optimal solution, but works for me. I created a utility program in Java to find all the method calls and compare the parameters to existing translations.
Find all classes in my project's root package using the Reflections library
Find all getTranslation method calls of the correct class in the classes using the Javassist library and create a list of them (contains: package, class, row number)
Read the appropriate .java files in the project directory from the given row until the ';' character
Extract the parameter value and add it to a list
Find the missing translations and output them
Find the redundant translations and output them
It took me a while to do this, but at least I now have a reusable utility to keep the translation files up to date.
I'm currently working on a Java project where I have a set of data which I wish to output in several custom formats. I have a class for each format, which takes the raw data and converts it accordingly. However, to begin with I am only implementing two or three of these formats, but wish to allow more formats to be added at a later date without having to do a massive rebuild of the application.
My idea was to create a DLL for each of the format classes, and have my application pass the data to be converted to each of these. This way, I can create a DLL later on and have my main application accessing it. (I would gladly listen to any alternative ways of doing this, as someone who has done this in C++/C# before this felt like the logical solution but it may not be applicable to Java)
My problem is that I have absolutely no idea how to do this - in C++/C# I could write this in a few lines of code but I'm not sure how it works with Java. At the risk of asking a terribly vague question, how can I do this?
Answers are greatly appreciated and cookies and tea will be offered. :)
Thanks in advance,
M
Edit: Sorry, just to add: I am also unsure how to create the DLL, which must be in Java for this project, to be read in the first place. Thanks. :)
Rather than using a DLL per se, it seems like what is wanted is a plugin architecture of some sort.
One reason why I wouldn't recommend using a DLL unless it is necessary is that linking Java code with native code will require using the Java Native Interface (JNI) which would probably require more effort than a pure Java solution.
One relatively simple way to do so is to use the reflection capabilities of Java.
From the information given, I would probably go along the lines of the following:
Define an interface for the output format.
Create a Java class implementing the interface.
Have the class available from the classpath.
Dynamically load the class using reflection. (Using the Class.newInstance method can instantiate objects from class files loaded by the ClassLoader.)
With these steps, it would be possible to implement a simplistic plugin which wouldn't require a full rebuild when support for a new format is required.
Step 1: Define the interface
Let's say we end up with an interface like the following:
public interface Outputter {
public void write(Data d);
}
Step 2: Make an implementation class
Then, we'll make an implementation class.
public class TextOutputter {
public void write(Data d) {
// ... output data to text
}
}
Then, compiling the above, we'll end up with a class file called TextOutputter.class.
Step 3: Make the class available from the classpath
When running the main application, we'll need to have the above TextOutputter.class in the classpath. Normally, one would tell the JVM a list of places to consider as the classpath, and that should include the above class file.
Once that is done, we should be able to load the above class using reflection.
Step 4: Dynamically load the class using reflection
Now, when we actually want to load the above class, we'd do something like the following:
// Note: We load the class by specifying the fully-qualified class name!
Class<?> clazz = Class.forName("TextOutputter");
// Then, we instantiate the class.
// Note that the following method will call the no-argument constructor.
Outputter outputter = clazz.newInstance();
// Now, we can give data to the TextOutputter object that we loaded dynamically.
outputter.write(...);
The Class.forName method is used to attempt to find the TextOutputter class from the default ClassLoader. Once we obtain the class as a Class representation, we can then instantiate an object of that class.
Instantiating the object can be performed by using the Class.newInstance method. If something other than the no-argument constructor should be used, the Constructor of the class would have to be obtained proceed to instantiate the object from there.
The object instantiates via reflection is then placed into a Outputter variable, so the write method can be called on the TextOutputter.
Adding more formats would entail the above process, but changing the fully-qualified class name (e.g. for String, the FQCN is java.lang.String) is all that is needed to load up a different class.
In a nutshell, that's what it will take to dynamically load class files and use it from your application.
(Just as a side note, I did not actually compile the above code, so there may be some errors here and there, but I hope I could illustrate the process it will take.)
I've made such things.
i created an open java based plugin architecture POJO based,that even did reload on the fly of updated plugin classes.
JNI is the interface for dealing with native code.
The only technical part was to rewrite a classloader that enabled DLL reloading dynamically at runtime.
But if you do only make "offline" updates, no such things are needed.
You can load a new DLL at any time with System.loadLibrary(). However you may need to load a java class for it to bind to.
You might find using an OSGi container helpful as this supports both load and unloading of modules (including shared libraries)
I would suggest using karaf with iPOJO but there are many others.
If you want write native codes (compiled to a DLL) to be used in java, you want to look at Java Native Interface (JNI).
Update you can use System.loadLibrary(String libName) (if you know the library name and the library path is set) or System.load(String filename) (library filename) to load library (DLL) in java.
I think you can ignore the JNI path. I have the impression you're using the term dll for lack of a better word, you don't really need a dll.
You could do the same thing in Java, but you'd put your filters in jar files instead of dll.
Define an interface for the file format filters to implement
Put each implementation into a jar, in a specific folder (like 'filters')
At one point in the app, iterate over the folder, generate classloader for the jars
Use reflection to find all implementations of your interface, and create a class for each
Call the methods to do their job
That's basically it.
Java SE 6 introduces the ServiceLoader class:
http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
If you want a proper modular approach consider the NetBeans Platform (especially if it is a desktop application) or OSGi.
I have set up UrlRewriterFilter (Tuckey) with many rules and it is working very good for my servlet. But I want to use the same config to rewrite urls outside servlet - in code that generates e-mails with urls.
So, I need to somehow start UrlRewriter (or some kind of wrapper) to process outgoing url i.e. rewrite them with my outbound-rules already defined in config (urlrewrite.xml).
I would like to use it just like this:
String prettyUrl = urlRewriter.rewriteOutgoingUrl(uglyUrl);
Is this possible at all? How to achieve this goal?
It's open source. You could review it's source code (http://code.google.com/p/urlrewritefilter/source/browse/trunk/src/java/org/tuckey/web/filters/urlrewrite/UrlRewriteFilter.java) and see if the logic is available in standalone class(es) which don't rely on servlet request/response objects. If it is, just use it. Otherwise you can build it yourself based on the original source, reusing as much of the library as possible.
You probably just need to initialize UrlRewriteFilter. Since you have to add this in your web.xml file normally the UrlRewriteFilter config files probably get loaded once. I would try loading this in a static initializer in some wrapper class you define. To define a static initializer all you need to do is within a class have the following:
static {
//Your initialization code goes here
}
This code will only be initialized once, during runtime. For more information please look here:
http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html
I'd like to run JSLint4Java as part of my build process. I have about 1000 JS files in a library, and don't really want to add a
/*globals foo, bar, baz */
header to each of them -- especially since many of them are from an external library (Dojo). If I don't add the header, though, JSLint complains about the same five globals on nearly every single file. Is there a way to tell JSLint to ignore them? Some things I've thought of so far:
Some sort of AntFileMap task that creates a virtual directory hierarchy that's an exact copy of another hierarchy, but has a filter applied to each file (in this case, prepend with a /*globals */ header).
Hack JSLint4Java to accept a set of globals which it prepends as a comment to the beginning of every file it processes.
I've never seen anything like (1). (2) seems relatively easy, but I'd prefer to use original tools if possible. Any better suggestions?
From http://www.ohloh.net/p/jslint4java
News 2009-12-02. jslint4java 1.3.3 is
released. Noteworthy alterations: Add
support for the predef option, to
allow specifying a list of predefined
global variables.
Sounds like what you might be looking for. Try the --help option to get the syntax, maybe?
You can also use LintRoller - a Node.js utility for checking entire directories or projects against JSLint, JSHint and other validations.