Getting a class' constant pool programmatically - java

Lets say I have class Foo:
public class Foo {
// ...
}
I want to get its constant pool as a byte array from another class. i.e:
public class Bar {
void butts() {
byte[] fooConstantPool = Foo.class.getConstantPool();
// ...
}
}
Class#getConstantPool is not part of the standard API. Is there any consistent way I can get another class' constant pool?

You can get it as sun.reflect.ConstantPool object via reflection like this:
import sun.reflect.ConstantPool;
public class Bar {
private static final Method getConstantPool;
static {
try {
getConstantPool = Class.class.getDeclaredMethod("getConstantPool");
getConstantPool.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
void butts() {
ConstantPool constantPool = (ConstantPool) getConstantPool.invoke(Foo.class);
// ...
}
}
but I'm not sure how to get it as byte array. You can try to serialize it :)

You can scan your class loader to find the class's location on disk, then use a framework like BCEL to analyze it.
I have a website demonstrating this, but StackOverflow says I am not allowed to post links to it.

Related

How to handle Exception from Singleton java?

I have a singleton class
public class SingletonText {
private static final CompositeText text = new CompositeText(new TextReader("text/text.txt").readFile());
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}}
And TextReader constructor that could throw FileNameEception
public TextReader(String filename) throws FileNameException{
if(!filename.matches("[A-Za-z0-9]*\\.txt"))
throw new FileNameException("Wrong file name!");
file = new File(filename);
}
How can I rethrow it to main and catch it there?
Main class
public class TextRunner {
public static void main(String[] args) {
// write your code here
SingletonText.getInstance().parse();
System.out.println("Parsed text:\n");
SingletonText.getInstance().print();
System.out.println("\n\n(Var8)Task1:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*", new FirstLetterComparator());
System.out.println("\n\n(Var9)Task2:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*", new LetterColComparator());
System.out.println("\n\n(Var16)Task3:");
String result = SubStringReplace.replace(SingletonText.getInstance()
.searchSentence(".*IfElseDemo.*"), 3, "EPAM");
System.out.println(result);
}}
Static block is executed only when class is loaded for the first time, so you can have something as below which will allow you to re-throw the exception. In you main method, you will surround getInstance() invocation in a try-catch block and then in catch you can do whatever you are looking for.
In case of exception, this exception will be thrown and re-thrown (from you static block) only once, at time of class loading. What #Alexander Pogrebnyak has said is also true.
Looking at the code you have provided, since you are always reading text/text.txt files so below approach will work. In case you are looking to read different files and then re-throwing exception then that becomes all together a different story, and you hadn't asked that part neither the code you have provided shows the same. In any case, if that's what you are looking for then:
you need to create a singleton object of your CompositeText class.
create a setter method will create an object TextReader class using the file name string passed.
that setter method will have the try-catch block, and in the catch block you will re-throw the exception so that you can catch again in main method.
P.S.: since static blocks are executed only once when class is loaded and class is loaded only once per JVM (until you have custom class loaders and overriding the behavior) so this ensures that this singleton is thread-safe.
Code:
public class SingletonText {
private static CompositeText text = null;
static{
try {
text = new CompositeText(new TextReader("text/text.txt").readFile());
} catch (FileNameException e) {
// TODO: re-throw whatever you want
}
}
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}
}
try to lazy initialze the singleton.
something like this:
public class SingletonText {
private static CompositeText text;
public SingletonText() {
}
public static CompositeText getInstance() {
if (text ==null) {
text = new CompositeText(new TextReader("text/text.txt").readFile());
}
return text;
}
}
Also, you need to declare the constructor private, and if it multi-threaded application you need to synchronized the new statement with double check locking. see this in wiki:
https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
Enjoy..
You will get java.lang.ExceptionInInitializerError when your singleton static initializer will fail.
As a cause it will have your FileNameException.
If you don't do anything, default exception handler will print the whole stack trace to standard error.

Accessing public methods of a Private Inner Class, from outside the Enclosing class

I have the following code class Agent.java :
public class Agent {
Helper helper ;
private class SpecificBehaviour extends Behaviour{
private Apple a;
public SpecificBehaviour(Apple a){
setApple(a);
}
public void setApple(Apple a){
this.a=a;
}
public Apple getApple(){
return a;
}
}
public void someMethod(){
helper = new Helper(this);
}
}
In the Helper.java ( another class within the same package) I would like to access the getApple() method. did some search and found this link
I am wondering if there is a better/ easier way of doing this ?
There are at least two issues here:
Helper doesn't know of the existence of SpecificBehaviour, because it's a private class. It could potentially know about the Behaviour class, which you haven't given any details of. If getApple() is declared in Behaviour, and if Behaviour is visible to Helper, then the visibility part needn't be a problem.
Helper will need a reference to an instance of SpecificBehaviour, which means you'll need to instantiate SpecificBehaviour. For that, you'll also need an instance of Agent, because SpecificBehaviour is an inner class. It's not clear whether you have such an instance.
Basically I think the presence of a private inner class is adding confusion here. If you're reasonably new to Java, I'd strongly recommend sticking to top-level classes for the moment. They have a few subtleties around them, and it's best to try to learn one thing at a time.
If this doesn't help, please give more context - your question is quite vague at the moment. Where do you want to use getApple within Helper? Should part of the state of Helper be a reference to an instance of SpecificBehaviour, or should it be a method parameter? Have you created an instance of Agent? What does Behaviour look like? You may find that in the course of answering these questions one at a time, you're better able to figure out the problem for yourself.
- Use Composition principle to get the access to the getApple() method.
Eg:
public class Agent {
Apple a = new Apple(); // Agent class has a reference of type Apple.
.....
.....
}
- Second way would be to make the getApple() method static in Apple class, and then access it from Agent class using the Class name with . (dot) operator.
Eg:
public class Agent {
public void go(){
Apple.getApple();
}
.....
.....
}
You need to ask the Agent object you are passing to the Helper for the instance of the private class SpecificBehaviour. This is the way it works. Encapsulation remember.
Jon Skeet stated that and I completely agree on it:
Helper will need a reference to an instance of SpecificBehaviour,
which means you'll need to instantiate SpecificBehaviour. For that,
you'll also need an instance of Agent, because SpecificBehaviour is an
inner class. It's not clear whether you have such an instance.
Actually, you can understand how weird your try is by testing the sample code below:
Agent.java
public class Agent
{
private class SpecificBehaviour
{
public String toString()
{
return "specific behaviour";
}
}
public Class getInner()
{
return SpecificBehaviour.class;
}
}
Helper.java
public class Helper
{
public static void main(String[] args)
{
try
{
Agent agent = new Agent();
System.out.println(agent.getInner().newInstance().toString());
}
catch (InstantiationException e) { e.printStackTrace(); }
catch (IllegalAccessException e) { e.printStackTrace(); }
}
}
The code above just compiles fine. And let's see what the output is:
java.lang.InstantiationException: Agent$SpecificBehaviour
at java.lang.Class.newInstance0(Class.java:340)
at java.lang.Class.newInstance(Class.java:308)
at Helper.main(Helper.java:5)

Double checked locking in modern JVMs

I have a class that might throw any run-time exceptions during initialization. I want the class to be a singleton since the cost of keeping several objects in memory is high. I am using that class in another class.
My use case is as follows:
I have to use a single instance of Controller.
Each instance of Parent must use the same Controller instance.
Controller
constructor might throw exceptions.
If instantiation fails, I should
retry to instantiate after sometime.
So I check if my Controller instance is null when I try to do a "get" on the Controller, if yes, I try to instantiate it again.
Following is my code:
class Parent
{
private static volatile Controller controller;
private static final Object lock = new Object();
static
{
try
{
controller = new Controller();
}
catch(Exception ex)
{
controller = null;
}
}
private Controller getController() throws ControllerInstantiationException
{
if(controller == null)
{
synchronized(lock)
{
if(controller == null)
{
try
{
controller = new Controller();
}
catch(Exception ex)
{
controller = null;
throw new ControllerInstatntationException(ex);
}
}
}
}
return controller;
}
//other methods that uses getController()
}
My question is, is this code broken? I read somewhere that the above code would be a problem in JVM 1.4 or earlier. Can you provide references/solutions? Please note that I am asking this question because there is a lot of confusion regarding this topic in the internet.
Thanks.
I believe it's not broken, cause of volatile declaration. But imho better to avoid code like this. There is no guarantee, that this code will work with Java 8 for example. There are another way to create lazy singleton. I always (almost) use this method. First time faced with it in Java Concurrency in Practice book.
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
I don't know what you are doing in your code, it's hard to say, how to tweak it. The most straightforward way, simply use synchronize method. Do you seriously want to receive some performance benefit using double-check-locking ? Is there bottle-neck in synch method ?
The only thing which is broken is to make the example far more complicated than it needs to be.
All you need is an enum
// a simple lazy loaded, thread safe singleton.
enum Controller {
INSTANCE
}
Using an AtomicBoolean (much like I suggested here) would be safer and allows for repeat attempts at instantiation on failure.
public static class ControllerFactory {
// AtomicBolean defaults to the value false.
private static final AtomicBoolean creatingController = new AtomicBoolean();
private static volatile Controller controller = null;
// NB: This can return null if the Controller fails to instantiate or is in the process of instantiation by another thread.
public static Controller getController() throws ControllerInstantiationException {
if (controller == null) {
// Stop another thread creating it while I do.
if (creatingController.compareAndSet(false, true)) {
try {
// Can fail.
controller = new Controller();
} catch (Exception ex) {
// Failed init. Leave it at null so we try again next time.
controller = null;
throw new ControllerInstantiationException(ex);
} finally {
// Not initialising any more.
creatingController.set(false);
}
} else {
// Already in progress.
throw new ControllerInstantiationException("Controller creation in progress by another thread.");
}
}
return controller;
}
public static class ControllerInstantiationException extends Exception {
final Exception cause;
public ControllerInstantiationException(Exception cause) {
this.cause = cause;
}
public ControllerInstantiationException(String cause) {
this.cause = new Exception(cause);
}
}
public static class Controller {
private Controller() {
}
}
}
Yes, it is guaranteed to work by the Java Memory Model on modern JVMs. See the section Under the new Java Memory Model in The "Double-Checked Locking is Broken" Declaration.
As other answers have pointed out, there are simpler singleton patterns, using Holder classes or enums. However, in cases like yours, where you want to allow for trying to reinitialize several times if the first try fails, I believe that double-checked locking with a volatile instance variable is fine.
It is not an answer to your question but this famous article on Double-Checked Locking is Broken explains well as to why it is broken for java 1.4 or earlier version.

Java: Only allow instantiation by one class

I want certain classes in my project to be pooled. And so I don't want to be able to instantiate these classes using: new SomeClass(), but instead obtain a new item from the pool using SomeClass.allocate().
I have this kind of code for each class that needs pooling.
public class GameObject
{
// Pooling: Provides a static method for allocation and a method for freeing
private static Pool<GameObject> pool = new Pool<GameObject>();
public static GameObject allocate() { return pool.obtain(); }
public void free() { pool.free(this); }
...
}
Now I can disable the normal way of instantiating by making the default constructor private, but the problem is that the pool needs to instantiate the class when it's created, and also when the pool needs to expand.
Is there some way to limit construction to only by the pool?
You have 2 options I can see: either make it an inner-class of the pool or make the allocate method package-private and put it in the same package as the pool.
EDIT: Ah. Just make the constructor private and then override whatever method the Pool uses to create new instances. As a (crude) example using your frame above:
public abstract class Pool<T>
{
public abstract T getNewObject();
public T obtain(){ return getNewObject(); }
public void free(T obj) {}
}
and
public class GameObject
{
// Pooling: Provides a static method for allocation and a method for freeing
private static Pool<GameObject> pool = new Pool<GameObject>(){
public GameObject getNewObject(){ return new GameObject(); }
};
public static GameObject allocate() { return pool.obtain(); }
private GameObject(){}
public void free() { pool.free(this); }
}
GameObject's constructor is happily inaccessible to anyone else.
As a last resort,you are able to use reflection. For other option,other people already tells.
I remember Spring container is able to init class that has private constructor. And I am surprised of that. I guess it also uses this trick. The benefit could be it is more generic.
public static void main(String... args) {
try {
Constructor c = GameObject.class.getDeclaredConstructor();
c.setAccessible(true); // solution
c.newInstance();
// production code should handle these exceptions more gracefully
} catch (InvocationTargetException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
Alterative: Don't try to make your code jump through hoops. Use static analysis to enforce rules like this. The tools will catch it if you accidentally do something that you didn't intend to.

Java - Call the main class (this) when i'm am into a method

I don't know how to do this (yes sorry, should be a must to know maybe).
It would be easy to explain with an example :
public class PageMenuLogin extends Container {
public PageMenuLogin() {
final ITextField login_user = this.createTextField();
login_user.setName("");
final ITextField login_pass = this.createTextField();
login_pass.setName("");
final IButton button = this.createButton();
button.setLabel("Login");
button.setActionHandler(new IActionHandler() {
public ClientActions onAction() throws Exception {
// I NEED TO UPDATE THE CONTAINER ITSELF HERE.
// HOW CAN I CALL "this"?
return null;
}
});
}
}
As you can see in the example, i need to call the "this" when i'm into that method.
I think everybody in java but markzzz know how to do this :)
PageMenuLogin.this?
when you create a object like this
button.setActionHandler(new IActionHandler() {
public ClientActions onAction() throws Exception {
// I NEED TO UPDATE THE CONTAINER ITSELF HERE.
// HOW CAN I CALL "this"?
return null;
}
});
You created a anonymous class(a class without name), take a look in binary class file dir, you'll see some class has name like PageMenuLogin$1.class, PageMenuLogin$2.class ... they are binary code of anonymous class. A anonymous class, Inner class can access its parent(top level) class object using syntax just as Tom's answer.
PageMenuLogin.this

Categories

Resources