i'm wondering about a specific syntax for the "code" attribute that's used with deployjava.
with something like code: applet.class it's fairly obvious that the call is pointing to a file of that name, presumably in the same directory as the file making the call.
sometimes, though, i see something like code: com.domain.applet.
what is that referring to, and where is that file located in the file structure relative to the script that's making that call?
with something like code: applet.class it's fairly obvious that the call is pointing to a file of that name, presumably in the same directory as the file making the call.
What is obvious is not necessarily the case.
The class might come from a jar, and won't be a loose class file in a directory.
The codebase determines the path to search for classes or jars. It defaults to the current directory when not specified.
Lastly, note that the class attribute should be the 'fully qualified class name'1, and that common nomenclature would have it named as EachWordUpperCase - something like GraphApplet.
sometimes, though, i see something like code: com.domain.applet. what is that referring to, and where is that file located in the file structure relative to the script that's making that call?
OK, let's again assume the applet is called com.domain.GraphApplet - that is the fully qualified name of the GraphApplet class, in package com.domain;.
If that were a loose class file, it would need to be in a directory like ${codebase}/com/domain/. Alternately it would need to be located in the /com/domain/ path inside a jar.
Last note on the FQN. It is common for programmers to add .class e.g. com.domain.GraphApplet.class. While tolerated, that is not correct. It should just be com.domain.GraphApplet
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 create jar file which is enbedded and called as applet from ASP.Net web forms application.
I use ResourceBundle to load localized strings from properties.
I created 3 properties files:
localizedStrings.properties
localizedStrings_de.properties
localizedStrings_en.properties
and load strings with
ResourceBundle labels = ResourceBundle.getBundle("localizedStrings", Locale.GERMAN);
However all strings are loaded from strange location : Login.aspx (which is in the same directory with this applet.jar)
When I call Collections.list(labels.getKeys()).get(0)
I see some contents of Login.aspx in there, very unusual, i have tried with some other bundle names and same results.
What could be the problem here?
I would not say it is strange location. Since you haven't provided any location really, the natural place to look for is the Java classpath. If you want to change it somehow, you need to use fully qualified name for base name, i.e.:
ResourceBundle.getBundle("com.my.company.localizedStrings", Locale.GERMAN);
The only doubt I have, since you probably use something like J# is whether that will work. It should.
I know that there is a "Check if a folder is empty", but it does not check for existing of the folder.
But to use it in Pentaho is more complicated. When creating a Job rather than a transform, straight Java is not directly available (that I know of). The good news is PDI's JavaScript interpreter is Rhino. That means all Java's objects and classes are available to JavaScript. As such the check is pretty easy.
Add a variable or parameter in your job and call it something like dirpath and give it a path to evaluate. Then add a JavaScript step to the job and add put the following code in it:
dirpath = parent_job.getVariable("dirpath");
fileobj = new java.io.File(dirpath);
fileobj.isDirectory();
Control will flow down the Success or Failure paths from this step based on the truth of the last line.
Pentaho will likely add that capability to their Check if File Exists step soon, but in the mean time, this will work. OTOH, might be another good example of a custom plugin that could be written.
The isDirectory() method of the File Object should do, what you need.
The Api writes:
Returns:
true if and only if the file denoted by this abstract pathname exists and is a directory; false otherwise
--> http://docs.oracle.com/javase/6/docs/api/java/io/File.html#isDirectory%28%29
On Job level you can use the step 'Checks if files exist' for checking the existance of files but folders aswell.
I am at a loss as to what has happened to my code. This used to work:
MyClass obj = (MyClass) Class.forName(extendedType).getConstructors()[0].newInstance(scan);
But now it is not loading. Instead it hits this line, stalls, and then exits. I have debugged it and know that is is happening somewhere in this line. Any suggestions would be greatly appreciated.
Note: Earlier today I refactored my code and ever since it has been giving me some naming issues. Mainly i changed packages names from uppercase to lower case (ie. Myclass.class to myclass.class). I don't know if this has affected something or not.
Update
extendedType is a string providing the full package and class name of the class I want to load. So, for example, com.biz.myclass instead of just myclass. The intent is to load a child class of a parent class depending on what the user chooses. There are other ways of doing this, but I want to know why this suddenly stopped working. And it stalls on Class.forName
refactoring Package is not perfect in many IDEs, try not to...
try to check the actual folder names that exist in the system.
if the folder names are as they were before then you have your problem.
if the original package name was lets say:
MyPackage
and then you refactored it to:
mypackage
then you might have to manually go and rename you folder structure accordingly.
try it.
I am currently reading a book on java, and I am currently studying the swing graphical user interface components. While I was doing so, I stumbled upon a code example, where the author was setting an image on a JButton with a very unusual way, depicted below:
Icon bug1 = new ImageIcon( getClass().getResource( "bug1.gif" ) );
In order for the above to work, you need to have the image on the same folder as the .class files. Can someone explain to me why is he using this particular code (which as far as I know, it must be reflection code, but then again, I am not particularly sure about this one) and if there is one way for me to do the same thing, without getting things as complicated as he does?
Things are complicated only if you don't understand them. Once you have understood what the above code does, it will be extremely simple.
getClass() returns the Class object of the current object (this). getResource() called with a relative path as above, looks for a file, in the classpath, named bug1.gif, and in the same package as the Class object being called. So it looks for bug1.gif in the same package as the class containing the above code. getResource() returns a URL. And the ImageIcon constructor takes a URL as argument, loads the image bytes from this URL, and constructs an ImageIcon from these bytes.
So the whole thing just creates an ImageIcon from a file available from the classpath, in the same package as the class calling this code. And this makes sense: you put the images used by a given class in the same package as the class, and you release a jar containing the classes and the images of the application.
You would have figured all this by yourself by reading the javadoc of all these methods.
Java's Swing can get over complicated really fast and I think he's actually using this code for simplicity.
If the image path is relative (the path in your example is), the image has to be located in the same location as the compiled byte code of your program, the .class files. If the image was anywhere else, your program simply couldn't find it.
Relative paths like this are very useful especially when you want to compile your finished project into a JAR file. Your image will be included in the JAR with all your .CLASS files. You will be able to download your compile program, run it, and your images will be right there in your GUI as you would expect.
Class#getResource(String) returns an URL to resource from the classpath. This is a convinient way of loading resources that are stored inside your application JAR file. If the image lies somewhere on the HDD, you can load it using:
new ImageIcon(new File("/path/to/the/image").toURI().toURL());
which creates the File object, and gets it's path as URL (which will look like file:///path/to/the/image).
Or even easier, as ImageIcon has a contructor that takes a fileName:
new ImageIcon("/path/to/the/image");