I've got a series of web actions I'm implementing in Seam to perform create, read, update, etc. operations. For my read/update/delete actions, I'd like to have individual action classes that all extend an abstract base class. I'd like to put the #Factory method in the abstract base class to retrieve the item that is to be acted upon. For example, I have this as the base class:
public abstract class BaseAction {
#In(required=false)#Out(required=false)
private MyItem item=null;
public MyItem getItem(){...}
public void setItem(...){...}
#Factory("item")
public void initItem(){...}
}
My subclasses would extend BaseAction, so that I don't have to repeat the logic to load the item that is to be viewed, deleted, updated, etc. However, when I start my application, Seam throws errors saying I have declared multiple #Factory's for the same object.
Is there any way around this? Is there any way to provide the #Factory in the base class without encoutnering these errors?
The problem you're encountering is that every Seam component needs a unique name - using your approach you'd have a component named "item" for each subclass.
I would do the following:
#Name( "action1" )
public class Action1 extends BaseAction
{
...
}
And in components.xml:
<factory name="action1Item" value="#{action1.item}" />
Related
When you are creating a new view the #Named annotation should be used. However, if the view should be an extension of a class that already exists, how should this be achieved. To overwrite a method in the class I use the following:
#ViewScoped
#Specializes
public class classB extends class A{
#Override
public String save(){
}
}
This allows me to keep the already generated entity.
But the view needs to have the following annotations:
#Named
#ViewScoped
#URLMapping()
public class classB extends class A{
//content
}
How should this be achieved in one class? Given the two annotations cannot coexist?
The answer to this question depends on how the entity was originally created. If you are extending a class that manages an entity, you must create a separate view. That means one named class that is an extension of the class managing the entity.
After this, you must create a correlating JSF page to that new named view that was created.
If there is a transfer of information, you must create a proper extended class with the specializes annotation to have access to the entity.
If you attempt to manipulate the entity in the new view class you will cause a merge error because the program already thinks the entity exists in the database.
I have a Spring bean (ChildBean extends Parent) which is extending an abstract class (Parent implements Runnable).
public abstract class Parent implements Runnable {
public final void run() {
// some code
}
public int overridenFunct() {
// some code
}
}
Child bean class variant which causes ClassCastException:
#Transactional
#Scope("prototype")
#Service("beanName")
public class ChildBean extends Parent {
#Override
public int overridenFunct() {
// some diff code
}
}
Everything works fine until I override public non-abstract method from parent class in child bean. After that a ClassCastException is thrown when I'm trying to create an instance of that bean.
Parent p = (Parent) appContext.getBean("beanName");
Bean object returned by getBean() is a ChildBean class instance (checked with debugger). Why does casting ChildBean object to its abstract parent class Parent not work?
So, without an overridenFunct() implemented in ChildBean everything works fine.
Could someone please tell what is the problem here?
UPDATE:
Changing method overridingFunct() to protected fixes the issue. But what if I need to override a public method? Is that allowed? I'm using Spring 3.2.8
UPDATE2:
Well, I didn't get to the point why overriding public method in abstract parent causes ClassCastException. As the resolution I did the following: created an interface with all public methods with common logic, an abstract class, which implements that interface and all "common" methods. Then all the child beans are extended from that abstract class, implementing its specific logic.
For anyone that may encounter this error, the following may prove to be useful in debugging this. First and foremost, the problem can be caused by the ClassLoader loading two copies of a particular class due to dependency overinclusion.
Supply the following option to your JVM via IDE or via
java -verbose:class {rest of your args / options}
Then, monitor the console output for the particular Parent class. A chance exists that the class has made it into the ClassLoader twice, perhaps by including a particular dependency more than once. Pay particular attention to the time when the bean is retrieved from lookup.
I was able to solve an issue on 4/22/2022 by using the above strategy to track down an issue in our Gradle build script that caused extra files to make their way into a WAR.
The Problem with your code is, that appContext.getBean("beanName") does not return an object that inherits from the class Parent.
A common mistake regarding classes with names like Parent is a wrong import.
Check if you are importing from the correct package.
If this does not fix the issue, make sure that appContext.getBean("beanName") returns the object you think it does.
It might return a Bean Object, that does not inherit from the Parent class.
The context also might not even contain your ChildBean object yet. Make sure it is added to it beforehand.
I've been working on Xamarin for the past couple of years along with Android studio and I decided to create an application for a friend (full source code here https://github.com/nekrull/waiter don't be too harsh please :) )
The idea is that there is a base activity which exchanges fragments when a new screen should appear.
Fragments have everything that has to do with user interaction and the activity they are attached to handles the business logic.
To do this I have a base class CoreActivity/DataActivity which has some methods most Fragments use (like blocking the back button) and some helper methods (like calling a method on an attached fragment of a specific class) , a CoreInteraction that responds to this activity and
CoreFragment/AttachedFragment which is used as the base of all view fragments
so for example the view fragment would look like this:
public class GroupsFragment extends AttachedFragment<GroupsFragment.GroupsInteraction> {
//this is what we expect to be able to call in the parent
public interface GroupsInteraction extends CoreInteraction {
Group get_shown_group();
void new_group();
void select_parent();
}
}
which is basically a fragment that expects its attached activity to be able to respond to the interaction methods.
the activity fragment would look like this:
public class MainActivity extends DataActivity<MainData> implements
GroupsFragment.GroupsInteraction, (other interactions here) {
}
The problem is that since the application I'm working on has only one Activity with many small screens, the code inside the base activity will get big, that does not cause a problem with the application or compiling or anything else. But it makes it really hard to find what I'm looking for easily.
What I used to do in Xamarin is something like this:
public partial class MainActivity : DataActivity<MainData> {
}
for the initialization activity and then each interaction would get its own file like this:
public partial class MainActivity : GroupsInteraction {
}
It had the same effect (since the class is compiled as a single class) but the code would be tidy and easy to read.
Obviously there are no partial classes in Java, but is there a way to delegate the implementation of an interface to another class?
Something along the lines of saying "when you're invoking a method from interface a, invoke it from that class" without actually writing stuff like :
public Group get_shown_group() {
return new GroupHandler(this).get_shown_group();
}
public void new_group() {
new GroupHandler(this).new_group();
}
public void select_parent() {
new GroupHandler(this).select_parent();
}
Thanks in advance for any help you can provide
Something along the lines of saying "when you're invoking a method from interface a, invoke it from that class"
Taking you literally what you describe is plain delegation, a class does not implement some or any functionality itself, instead it wraps a class implementing the desired functionality, calling the methods of said wrapped class. You could even switch implementation at runtime, just changing the wrapped class as you go (assuming the classes share a common interface, of course). Of course that does not "spare" you from writing the delegations yourself.
class Wrapper implements GroupsInteraction {
private final GroupInteraction gi;
public Wrapper(GroupsInteraction gi) {
this.gi = gi;
}
Group get_shown_group() {
return this.gi.get_shown_group();
}
// ... other interface impls
}
Additionally, you should keep the GroupHandler as a member instead of creating a new Object each time, so
public Group get_shown_group() {
return new GroupHandler(this).get_shown_group();
}
becomes
public Group get_shown_group() {
return this.groupHandler.get_shown_group();
}
You can try Delegation Pattern
BaseActivity {
MyDelegateClass delegate;
void example() {
delegate.example();
}
}
P.S. both activity and delegate implements same interface
Details here
I have an abstract class that a child class extends. My abstract class has an #Activate method, so does the child class. When OSGi creates my service, it invokes the child class activate method but never the abstract class's activate. Is there any way to force the abstract class's activate to be called by OSGi rather than having the child class manually call the parent activate method?
Here is some code to help elaborate on what I am asking.
#Component(componentAbstract=true, inherit=true)
#Service(value=ISomeInterface)
public abstract class AbstractHello implements ISomeInterface{
#Activate
public void activate(){
System.out.print("Hello ");
}
}
#Component
#Service(Value=ISomeInterface)
public class World extends AbstractHello{
#Activate
public void activate(){
System.out.println("World!");
}
}
The result of the code above would be "World!", rather than "Hello World!".
Initially I thought maybe the child activate method name was clobbering the abstract activate method of the same name. The result is the same even if the abstract class's activate method is given a unique name. Is there any way to have OSGi call the abstract class's activate method for me?
The DS annotation processors only look at the concrete class decorated with #Component. Super classes are not examined. Since the annotation processing is done at build time, super types may come from imported packages which are not chosen until runtime.
Also, the annotation processor generates component description XML from the annotations. So there can only be one activate="methodName" attribute in the XML. If you need the superclass' method called, then you need to call it from the subclass' method.
This has nothing to do with Apache Felix and OSGi, this is caused by poor understanding of Class Inheritance and Method Overriding in Java.
Your World class extends AbstractHello class and overrides its activate() method. If you want the AbstractHello.activate() method to be called then you must call it in
// Annotations excluded for readability.
public class World extends AbstractHello {
public void activate() {
super.activate();
System.out.println("World!");
}
}
OSGi can't help here.
UPDATE
Since the base class is abstract, and you don't have an instance of it, you can't call its method. Neither can OSGi container.
I am creating a Java library, as a final product in intend to distribute this .jar to developers.
I am "translating" my library from Objective-C where I control which classes header files are available to the developer. In other words I am only exposing to the developer a few classes they can handle.
In my Java library I am using packages and my package has grown quite big. So I decided to separate into different packages my models and controllers. But now the models I wanted to keep private I need to mark as public in order to use from the main package.
My question is does this go against what I was doing in Objective-C ?
For example I have an Event class which is really only used internally and I don't want the user to know about it or think about it. I have another class TimedEvent, which the user can get an instance of an manage.
In my Objective-C, I simply excluded Event class from the library public scope, allowing TimedEvent.
If I am making things more tidy in my library then it seems packages aren't the way. Since now, my main controller is in the main package and all the models are in another package - forced to have a public scope.
Opinions ?
This is possible with Java but there are reasons why (almost) no one does it...
If you put the implementation and the interface into the same package, then you can omit all access modifiers (private, protected, public) from classes and methods to give them "default" or "package" visibility: Only classes in the same package are allowed to see/use them.
Drawback: You'll have to mix API and implementation.
The other approach is to move the implementation into a package *.private.*. No more mixing of API and implementation but malicious users can easily access the implementation - it's just a naming convention. Like a STOP sign: It means something ("be careful") but doesn't actually stop you.
Lastly, you can implement the interface inside of the interface. For example:
public interface IFoo {
String getName();
private static class Foo implements IFoo {
public String getName();
}
public static class FooFactory {
public static IFoo create() { return new Foo(); }
}
}
Ugly, ain't it?
The common approach to controlling exposure of your classes to the world is hiding implementations behind interfaces and factories.
Create an interface for your TimedEvent, and a class for creating instances of TimedEvent interface
Put the interface in the main package, and the factory in a sub-package
Give the factory public visibility
Implement the interface in the sub-package, giving it package visibility
Create an instance of the class implementing the TimedEvent interface in the factory
Here is an example of how you can do it:
package com.my.main;
public interface TimedEvent {
void fire();
}
package com.my.main.events;
import com.my.main;
public class EventFactory {
public TimedEvent makeTimedEvent() { return new TimedEvent (); }
}
// TimedEventImpl has package visibility - it is not public.
class TimedEventImpl implements TimedEvent {
public void fire() {
// Fire a timed event
}
}
The users would access TimedEvent like this:
com.my.main.events.EventFactory f = new com.my.main.events.EventFactory();
com.my.main.TimedEvent evt = f.makeTimedEvent();
evt.fire();