Java Class.forName() method stalling and then exits - java

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.

Related

Get content of a package

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.

How to Run a Java class from another class from another folder

I'm making a testing tool. For this, I need to access a class which is present in Test folder within same project.
I've a class mutant.java in src folder. And I've another class TestAll.java which is present in Test folder within same project. I need to access TestAll.java class in mutant.java class. But I can't be able to find a way to do that.
public void runTest()
{
TestAll a=new TestAll();
}
When I create an object of TestAll.java class in mutant.java class, It gives me an error and didn't recognize that class. I want to access TestAll.java class but don't know How can I?
I need to access TestAll.java class in mutant.java class
No, you need to understand how to properly organize the dependencies within a project.
Your "production" code, that stuff that sits in src is never ever supposed to use something from the test folder. End of story.
Reasoning: src represents the content that you "ship" to your customer. That is your product. Your own test code is not your product. In order to prevent you from (accidentally) releasing "test stuff" to your customer, you ensure that src can't use test. That is why any IDE or build tool organizes your project based on that simple rule.
Thus, the real answer is: you should step back, and rethink what you intend to do. The purpose of any test is to prepare some sort of setup, to then run some production code, and verify the expected behavior.
If your current design prevents that, then, as said: stop right there. Ideally, look out for some peer/tutor to sit down with you and rethink your design, and change it accordingly.
Every second you invest into "how do I use stuff from test within src" is a waste of your energy.

Where is the proper place to put my own Java code that isn't a Service, Activity, Fragment, etc.?

I read somewhere that all Java code I write should be under the com.my.package (just an example) in the src folder. Is this true? I really don't want to clutter that space with tons of java files (especially the crucial ones like activities, fragments, etc.).
Examples of code I want to place somewhere: A class that takes care of UI Fading, a class that validates emails, etc. I was thinking of putting them under libs, but I was told that is for external libraries not written by me.
just add a new package (ie a sub folder). something like com.my.package.mystuff or com.my.package.utils or something similar. That way you can keep your code separated.
you should be putting them in the main source folder as you said. However, you can have subpackages to avoid things becoming too cluttered. (com.my.package.sub.MyClass). One common pattern I've observed in Google apps is putting activities/fragments in a UI package to keep them clear from the rest of the code.
Make additional packages to organize your files. Typically all of your code should live at least under com.my.package, but not necessarily at that level. For example:
com/my/package
com/my/package/utils
com/my/package/fragment
You can organize it just like any directory structure. There are differences though, since if you have package private fields (e.g. String x instead of private String x they will not be accessible to classes outside of the same package).

Renaming a lot of variables in many Java classes at once

I work in a pretty large Java-project (2500+ classes) that uses an old code standard where all
member variables are prefixed with "m_" (e.g m_temperature). There is really no reason for this any longer and I'd like to get rid of them but:
In order to make the change I must do all variables at once.
It must not generate any bugs.
The first naive approach of simply renaming all the "m_variable" to just "variable" will not be sufficient as that could produce name collisions between an already existing variable named "variable", and the newly renamed one.
So, to sum up:
How do I rename all these pesky member variablest without getting into trouble and are there any more problems than the one mentioned above?
Yes, I'm aware of the refactoring/renaming features within IDEs, please bear in mind that I want to do the changes to all variables matching the criteria at once and not by right-clicking on variables and renaming them one-by-one.
How about below from : mass renaming of java variables
by Simulant
click on the variable name.
1:press [alt] + [shift] + [R]
2:enter the new name.
3:press [enter] to confirm.
-->all instances of this variable will be renamed.
Theres a question on SC which is about a massive refactoring in java too. The best answer is using japvaparser and implementing a visitor to do the actual refactoring. This shouldn't be that much work for a simple rename.
To answer your second question (are there any more problems)
I would avoid global variables. Favour encapsulation such that you can localise functionality.
I would implement some unit tests such that you can verify future changes. At the moment it appears your only available check is that your project compiles properly.
I realise both of these are potentially sizable issues in an existing project. But it's worth lookingto identify possible pain points and work on those first of all.
Refactoring tool will help in this case. When you rename a variable, it will rename it in all dependent places including if it is called in different class file. While doing this, it will alert you in case if your renamed variable matches with already existing name.
However we have to do it manually for each variable.
I don't know if this can work.
But I find this link to find and replace all occurence in a project using IntelliJ.
http://www.jetbrains.com/idea/webhelp/finding-and-replacing-text-in-project.html
If you are using eclispe IDE, you can do it in easy manner.
Steps:
select the variable
right click on it
click on refactor
click on rename
even in netbeans you can follow same steps.
The IDE finds the reference and usages and replace it all.

Can I compile a class along with all of its inner classes to a single class file?

I've been working on a fairly simple project for a class. I knew it was supposed to be written in Java, and I read enough of the Assignment description to have an idea what I was supposed to be doing, so I set about creating a nice, object-oriented solution ('cause it's Java, right?). When I finally get to reading the nitty-gritty details of the assignment, I come upon this little gem: The whole thing is supposed to be submitted as a single class file. It's too late to rewrite the whole thing now, so I tried to work around it by making all my classes static inner classes of the primary class. To my chagrin, I discovered that eclipse, at least by default, compiles the inner classes to separate class files still. I unfortunately don't know much about Java compiler settings, but I'm hoping theres a way to get them all compiled to one .class file. Is is it possible, or must I simply turn in what I've got with a note and take whatever my TA decides to dock me for it?
I'm afraid there is no such option. Each class is defined in its own class file. Even anonymous classes are defined in ParentClass$1.class
What I would suggest is to put a huge comment/documentation on why you think it is not good to put everything in one class. Of course it depends on the person "on the other end".
If one file, rather than one class is required, simply make a jar file.
If you are feeling brave you could create a jar for your application, encode it as a string in a your toplevelclass which extends a classloader and use this classloader to load the classes from the decoded jar file.
This is so crazy and shows so much knowledge of the Java platform it has to be worth extra credits.
As a TA, if a student send me a single java file, with an object-oriented design and nested classes, I would love it!
If the TA wanted the simplest solution to the problem and you over-engineered it, than it's of course another story.
Note that if the TA does not like nested classes and think they are bad, point him to NewSpeak and Gilad Bracha's posts. He's been involved in the Java Language Specification, he is an authority in the field and came up with a language entirely based on class nesting!
That said, should this be a single file, or single class file. If the former you can of course ZIP/JAR it, if the latter a little chat with the TA would be the way to go.

Categories