How to call getClass() from a static method in Java? - java

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");

Related

Java - passing an object as a parameter vs. using it's qualified name

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.

Maintain path constants for RestControllers

I'd like to know whats the common style to maintain path constants for Rest Controllers.
For example you have something like that:
#RequestMapping(method = RequestMethod.GET, value = ANY_PATH_VALUE)
I do maintain those constants (in the example ANY_PATH_VALUE) at the moment in a class called PathConstants which looks like this:
public abstract class PathConstants {
public static final String ANY_PATH_VALUE = "/path/{SOME_ID}";
...
}
Is it a common way to keep those values straight at the method of the RestController class or is it like I do currently? Or is there a even more common way how to maintain this kind of stuff?
There are two sides to this,
It actually has close to zero performance problem. This has to something with readability.
The first view is keeping the values as native strings there itself in the controllers. This is more readable in the sense that you can directly check the exact API route when you enter the controller.
The second view is keeping it in some other file with static constants. Keeping all the routes like this actually gives you one common place where you can get to know all the API routes you currently support in your application.
I personally prefer the second i.e. keeping all the paths in a file called APIRoutes and further divided by domains.
public class APIRoutes {
public class SYSTEM {
public static final String HEALTH_CHECK = "api/v1/healthcheck";
public static final String LB_HEALTH_CHECK = "lb/v1/healthcheck";
}
public class API {
public static final String SAVE_X = "api/v1/save";
public static final String GET_X = "api/v1/get";
}
public class CACHE {
public static final String RELOAD_X = "cache/v1/load/x";
public static final String RELOAD_Y = "cache/v1/load/y";
}
}
This way in your controller, you have something like
#RequestMapping(method = RequestMethod.GET, value = APIRoutes.API.SAVE_X)
Using constants seems to be a quite reasonable approach. I would, however, define the constants in a final class with a private constructor throwing an AssertionError to enforce noninstantiability:
public final class PathConstants {
// Suppress default constructor for noninstantiability
private PathConstants() {
throw new AssertionError("No instances for you!");
}
public static final String PATH_TO_FOO = "foo";
public static final String PATH_TO_BAR = "bar";
}
Quoting the Item 4 from Effective Java 3rd edition from Joshua Bloch:
Because the explicit constructor is private, it is inaccessible outside the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive because the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown earlier.
As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.
You also could use something like #RequestMapping("${foo.bar}"), where foo.bar is a value defined in a property souce (such as an application.properties file or YAML variant).
Quoting the Spring MVC documentation:
URI path patterns can also have embedded ${…​} placeholders that are resolved on startup by using PropertyPlaceHolderConfigurer against local, system, environment, and other property sources. You can use this, for example, to parameterize a base URL based on some external configuration.
I think it is a reasonable way to maintain paths. Just make sure you always build the paths from other constants. For example, if your path has version, you define the version as another variable.
public static final String VERSION_1 = "/v1";
public static final String USERS_V1 = VERSION_1 + "/users";

Read from property file in interface

i was wondering if it's possible to initialize a constant in an interface from a property file using java or using spring messageSource, or such thing is not possible
please advise, thanks.
You can:
public interface Foo {
String a = Properties.getProperty("foo"); // public static final by default
}
However, that means that Properties.getProperty(..) has to be a static method which relies on an already initialized message source (statically again). Depending on the project and the frameworks you use this might not be the best option.
You could initialise a bean via a configuration which includes a final member. Since it's final you can assign to it during construction/initialisation and it then is immutable.
To configure from a property file using Spring, check out the PropertyPlaceholderConfigurer. That will allow you to initialise Spring beans using one or more property files from your classpath, filesystem, remote services etc.
Yes, that's possible:
public static final CONSTANT = System.getProperty("myProperty");
Although it's possible using some static helper method (as was already suggested), I would strongly recommend you not to do so for 2 reasons:
That looks like a pretty bad design. If you need a dynamic value - make it a method in the interface. Or use a static helper directly - you will need one anyway to make it work.
Constants might be inlined at compile time. That shouldn't happen in this particular case - compiler should go with inlining only if it can prove that value won't change between executions, basically if you initialize it with a literal, But there is a tiny chance that it would. Just think how bad will it be - no matter in which environment the progran is running, it picks up some useless value set during compilation, instead of what is configured. (This is rather a theoretical problem, need to say).
by reading a property file like in the example below.
int property1;
String otherProperty;
public void loadProperties(File propFile) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(propFile));
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("Property1=")) {
property1 = Integer.parseInt(line.substring(10));
}
if (line.startsWith("OtherProperty=")) {
otherProperty = line.substring(14);
}
}
}

Java Using Strings as Code

Okay, so, here's what I have in code:
public void makeObject(int i){
String s = getString(i); //This returns the name of a class
new s(); //This is what I want to do
}
Can I do this?
No you can't do this, but what you're probably looking for is called 'reflection'.
Look at these series of (free) slides: http://www.slideshare.net/CiaranMcHale/java-reflection-explained-simply especially slide 11, but read the ones before that as well. It will give you an idea of what reflection is and a way to make a class by knowing the name (as a string) and how to instantiate a new instance of that class.
You can also find methods and fields by name, you can even modify existing classes in code.
Edit: for example the following code will return a class by string name
Class cls = Class.ForName("MyPackage.MyClassName");
return cls.NewInstance();

How to get arguments passed to method that called this method?

In Java, it is possible to get the class and method that called the current method (the method in which you get the StackTrace).
Can I get the arguments that were passed to the method that called this method?
I need this for debugging purposes.
Eg:
baseClass {
initialFunc(input) {
var modifiedInput = input + " I modified you";
otherClass.doSomething(modifiedInput);
}
}
otherClass {
doSomething(input) {
//GET THE ARGUMENTS PASSED TO THE METHOD OF THE CLASS THAT CALLED THIS METHOD
}
}
Can one get this information from the stacktrace, or are there other means?
(Note that I need to be able to do this in runtime and cannot actually change the source of baseClass, this is going to be a feature of my debugging class that does not know the source beforehand)
I don't believe this is possible using the standard Java API.
What you could do is to use AspectJ, place a point-cut at the calling method, save the arguments, place a point-cut at the called method and pass on the arguments.
Another option (slightly more advanced) is to use a custom, bytecode-rewriting, class loader that saves the original arguments, and passes them on as extra arguments to the next method. This would probably take a day or two to implement. Suitable frameworks are BCEL or ASM.
I think this could be possible, because input is out of scope but isn't yet accessible for garbage collection, so the value still exists, but unfortunately I don't believe there is an default API way to access it. This could be maybe possible with a custom implemented NDC (nested diagnostic context) for the logging approach.
I'm not sure why you'd ever want to do this in Java?
The only way I can think of is to create a custom wrapper object for the passed string, thus sending the reference to the wrapper instead of a new string each time.
I'd advice against it, though, since it clutters your original code, and makes it even more error prone.
Might this problem not be solved using a debugger, like the one built into eclipse, to inspect your state?
In my case, I needed to get a parameter value has been passed to a method in a certain stack frame to be used later within the execution flow
I used ThreadLocal to store it and when I needed it I was able to retrieve it at any point in code as I declared it as public static
here is a skeleton example
public static final ThreadLocal<SomeType> IMPORTANT_THREAD_LOCAL_FOR_BLA = ThreadLocal.withInitial(whatever);
methodWithImportantParam(SomeType importantValue){
// save it in the static threadLocal Field
this.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()=importantValue;// code to set the value
// continue method logic
}
and somewhere in code where you need that value
YourClass.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()
but make sure the execution flow that you set the value then you retrieve it
hope my answer add something valuable to this question
You can get name of caller method and its class, but you have to add some code in current method:
public static void main(String[] args) throws Exception {
call();
}
private static void call() {
Exception exception = new Exception();
for(StackTraceElement trace : exception.getStackTrace()){
System.out.println(trace.getMethodName());
}
}
This will print "call" and "main", methods name in called order (reverse).
This is possible using Reflection API !
public class StackTrace {
public static void main(String args[]) {
StackTrace st = new StackTrace();
st.func();
}
public void func() {
OtherClass os =new OtherClass();
os.getStackTrace(this);
}
}
class OtherClass {
void getStackTrace(Object obj) {
System.out.println(obj.getClass());
}
}

Categories