I'm having trouble understanding one of the guidelines set by my instructor:
• A public static final String that is assigned the value fx.prp.file.name. This is the context initialization parameter key for the relative path to the property file /WEB INF/fxCalc.prp
While using the code
public static final String codes = "fx.prp.file.name";
i get the error
cannot find symbol
symbol: variable codes
location: class SimplifiedJSPServlet
when i call it from the java file to the jsp file
EDIT:
After this, i have to call it back on a JSP
Inside of jspInit you can use the getServletContext method to get a ServletContext object. This object is available to all JSPs. The object has a method call getInitParameter that allows you to retrieve a param-value if you give it a param-name. The param-name, fx.prp.file.name, should be a
public final static String constant inside of FxDataModel. Do not hard-code anything.
It's going to act as a reference, simply surrounding the words in quotes doesn't seem to work
Make it
public static final String codes = "fx.prp.file.name";
if you want to assign literal value "fx.prp.file.name" to referencecodes
Related
I am writing a Java program where a method in one class needs to access a method of an object that is a member of another class. I can do this in at least two different ways, passing as a parameter, or directly accessing the object using the name of the class it is a member of. I find a lot of questions about pass-by-reference vs. pass-by-value, but I can't find anything that addresses this scenario.
Here is some pseudo-code showing what I mean:
// class of object to pass
class MyPrefs {
public String getPref(int i){
String s = ... //some code to get a String indexed by i
return s;
}
}
// class where object is instantiated
class Main {
protected static MyPrefs prefs = new MyPrefs();
}
Here are the two options I am looking at. In a third class, Toolbar, I can do either of these:
// pass as parameter
class Toolbar{
public void applyPrefs(MyPrefs p){
String s = p.getPref(1);
...
}
//or use qualified name of object
class Toolbar{
public void applyPrefs(){
String s = Main.prefs.getPref(1);
...
}
}
It works either way, what I would like to know is what are the merits or problems associated with each method, and if there is another way of doing this that I hadn't considered.
I hope this question doesn't get closed for being opinion-based because technically it is. So, I am not going to claim my answer is based on some undisputed best-practice, but I do believe it is generally accepted as the correct approach.
In my opinion, it would be either a variant of the first, and/or a combination of the two. For example:
public static String getProp(String prop) {
// use java.util.Properties to retrieve the property.
}
This works well when your application has a single property file. In cases you have multiple property files, you need to override this method and pass the path to the correct file.
public static String getProp(String filename, String prop) {
// use java.util.Properties to retrieve the property.
}
Where filename could be just the file name or the fully qualified name (with the path). I tend to keep all my property files in the same folder, so I "hard-code" the path and use that as the base location for my files, so most of the time when using this approach, I only need the actual file name.
I also have created utility methods to obtain specific properties where the name of the method implies what property I am obtaining. This is useful for people that are not too familiarized with the property keys.
public static String getXYZProp() {
// use java.util.Properties to load the properties.
return prop.getProperty("XYZ");
}
Alternatively, you should take advantage of the genetic method you created to do the same
public static String getXYZProp() {
return getProp("XYZ");
}
Or even something like
public static String getXYZProp() {
return getProp("someProps.properties", "XYZ");
}
It is OK to have multiple method that ultimately do the same thing. Think that some users will call the generic ones because they are more familiarized with the property keys while others will rely on method with names that help them figure out what properties they need to retrieve.
Can you help me understand why we call the parent class here? I found a download class that seemed simple enough but could use help wrapping my brain around the first method.
public class DownloadHandler {
public static void main(String[] args) throws Exception {
DownloadHandler d = new DownloadHandler();
d.URLSetUp(args[0]);
}
....
}
I am trying to instantiate the handler in a for loop and getting an error.
DownloadHandler file = new DownloadHandler("http://example.com/"+cleanLink+"/"+filename+".pdf")
It says "DownloadHandler() in DownloadHandler cannot be applied to (java.lang.String)"
Your DownloadHandler class has a static void main method, which is the single point of entry when executing command-line programs.
That method is not a constructor.
What it does is initialize a new instance of DownloadHandler and invoking an instance method on that object by passing the given String argument.
Not sure what's the usage there.
In order for your initialization to compile, you probably want to add a constructor that performs similar operations, given a single String parameter in your case.
For instance:
public DownloadHandler(String s) {
URLSetUp(s);
}
Java adds a default constructor to every class that doesn't provide one. A constructor is a method without a return type. So, in your case the default constructor DownloadHandler() is automatically added to your class and it does not take any parameters while you are trying to initialize it with a String.
The String you are using in main method right now is coming from console from user.
From your code its obvious that you want to pass a argument via command line parameter. But when you are initiating DownloadHandler, you are passing that string here which is not you should be doing.
There are two things you can do now.
Pass the string via command line parameter
java DownloadHandler yourstring
Write a constructor which accepts the string. In your code outside of your main method
String url;
public DownloadHandler(String str)
{
url = str;
}
Now call
d.URLSetup(url);
Hope this will clear your doubts.
I have checked the tutorials and this should work but it doesn't. I have a string in one class that I want to use in another, but when I do, I get a null exception.
#ViewScoped
#ManagedBean
public class FileDirectoryViewer {
FileUploadController destination = new FileUploadController();
NewDestination = destination + username + "/";
And I am trying to get the destination from
#ViewScoped
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
public String destination = "D:/Documents/NetBeansProjects/printing~subversion/fileupload/Uploaded/"; // main location for uploads
How do I get the destination from FileUploadController to FileDirectoryViewer?
The destination field of FileUploadController, has no access modifier, so it is package private by default.
If those two classes are in the same package, you can access it by creating an instance of the class, and using the . operator on the instance to access the property:
FileUploadController controller = new FileUploadController();
NewDestination = controller.destination + username + "/";
If they are not, you should implement a public String getDestination() method in FileUploadController that would return destination. You should call this method also by using the . operator: controller.getDestination().
Take into account there are several issues with the code you posted:
You're placing code outside a method in the FileDirectoryViewer class. In a class you can only define members (such as fields, or methods). Generally speaking, behavorial code goes inside of method declarations.
Using a hardcoded variable for a path property can be considered bad practice. Look into java.util.Properties for a start. Anyway, by the looks of the code, it doesn't make sense for the destination field to be an instance field, it could be static or defined in an interface.
Naming conventions for java recommend variable names to be camel case, and starting with lower case letters.
I have a class that must have some static methods. Inside these static methods I need to call the method getClass() to make the following call:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
However Eclipse tells me:
Cannot make a static reference to the non-static method getClass()
from the type Object
What is the appropriate way to fix this compile time error?
The Answer
Just use TheClassName.class instead of getClass().
Declaring Loggers
Since this gets so much attention for a specific usecase--to provide an easy way to insert log declarations--I thought I'd add my thoughts on that. Log frameworks often expect the log to be constrained to a certain context, say a fully-qualified class name. So they are not copy-pastable without modification. Suggestions for paste-safe log declarations are provided in other answers, but they have downsides such as inflating bytecode or adding runtime introspection. I don't recommend these. Copy-paste is an editor concern, so an editor solution is most appropriate.
In IntelliJ, I recommend adding a Live Template:
Use "log" as the abbreviation
Use private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class); as the template text.
Click Edit Variables and add CLASS using the expression className()
Check the boxes to reformat and shorten FQ names.
Change the context to Java: declaration.
Now if you type log<tab> it'll automatically expand to
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
And automatically reformat and optimize the imports for you.
As for the code example in the question, the standard solution is to reference the class explicitly by its name, and it is even possible to do without getClassLoader() call:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
This approach still has a back side that it is not very safe against copy/paste errors in case you need to replicate this code to a number of similar classes.
And as for the exact question in the headline, there is a trick posted in the adjacent thread:
Class currentClass = new Object() { }.getClass().getEnclosingClass();
It uses a nested anonymous Object subclass to get hold of the execution context. This trick has a benefit of being copy/paste safe...
Caution when using this in a Base Class that other classes inherit from:
It is also worth noting that if this snippet is shaped as a static method of some base class then currentClass value will always be a reference to that base class rather than to any subclass that may be using that method.
In Java7+ you can do this in static methods/fields:
MethodHandles.lookup().lookupClass()
I wrestled with this myself. A nice trick is to use use the current thread to get a ClassLoader when in a static context. This will work in a Hadoop MapReduce as well. Other methods work when running locally, but return a null InputStream when used in a MapReduce.
public static InputStream getResource(String resource) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(resource);
return is;
}
Simply use a class literal, i.e. NameOfClass.class
Try it
Thread.currentThread().getStackTrace()[1].getClassName()
Or
Thread.currentThread().getStackTrace()[2].getClassName()
getClass() method is defined in Object class with the following signature:
public final Class getClass()
Since it is not defined as static, you can not call it within a static code block. See these answers for more information: Q1, Q2, Q3.
If you're in a static context, then you have to use the class literal expression to get the Class, so you basically have to do like:
Foo.class
This type of expression is called Class Literals and they are explained in Java Language Specification Book as follows:
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a `.' and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
You can also find information about this subject on API documentation for Class.
I had the same problem !
but to solve it just modify your code as following.
public static void startMusic() {
URL songPath = YouClassName.class.getClassLoader().getResource("background.midi");
}
this worked fine with me hope it will also work fine with you.
Suppose there is a Utility class, then sample code would be -
URL url = Utility.class.getClassLoader().getResource("customLocation/".concat("abc.txt"));
CustomLocation - if any folder structure within resources otherwise remove this string literal.
Try something like this. It works for me. Logg (Class name)
String level= "";
Properties prop = new Properties();
InputStream in =
Logg.class.getResourceAsStream("resources\\config");
if (in != null) {
prop.load(in);
} else {
throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
}
level = prop.getProperty("Level");
Is there a way to run class X's methods from another class (in the same project but different package) when I only have class X's name stored in a String - say I don't know what classes exist until my program starts and I scan the directory for .java files then store those names into Strings.
So for example I have class A, which has functions 'main' and 'method1' - my program gets the name of class A from its file into String s. Then I want to be able to run the main or method1 functions but am unsure how to manipulate s to get there...one thing I've tried is this but I simply get the Exception error and don't know if it's on the right track, any suggestions?:
//gets the filename from JFileChooser method_fc
File file = method_fc.getSelectedFile();
try {
Class c = Class.forName(file.getName());
Method method = c.getDeclaredMethod("main");
Object instance = c.newInstance ();
Object result = method.invoke(instance);
} catch (Exception e) {
System.out.println("Cannot access class: "+e.getMessage());
}
You can do that but take into consideration that class name does not end with ".java" or ".class" (you can remove it).
My guess is that your main method has a String[] parameter, but you're not supplying it - or it's a static method, but you're trying to call it as an instance method.
However, it's hard to tell without seeing with the class or the error message.
As Fernando notes, the name of the class isn't the same as the name of the file - not only would a filename end in ".class", but there might also be packages involved - a file "Foo.class" may actually contain a class "com.acme.Foo".
EDIT: As noted in comments, the class will also need to be in the classpath, or a special ClassLoader will be required.
main is usually a static method with a String[] parameter. If so, you don't need an instance - use the Class object itself as the target object.
This fragment works on a standard main method:
Class<?> c = Class.forName("com.company.SomeClass");
Method method = c.getDeclaredMethod("main", String[].class);
method.invoke(c, (Object) new String[] {});
please report the full stack of the exception.
I guess that your main method receive as parameter at least an array of string. Furthermore the main method usually doesn't return any result because it is defined as void.
Why didn't you pass args to the method invoke?
String[] args = new String[1]
Object result = method.invoke(instance, args);
Please report at least the declaration of the main method.
Regards,
Luca