Minecraft RegistryObject not present - java

I'm a new minecraft modder, and I'm trying to make a new mob bucket item.
Everytime I run the game, the game crashes saying that the RegistryObject for my modded entity isn't present.
Here is the code in question:
public class ItemInit {
private ItemInit() {}
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, TheDeepBlue.MODID);
public static final RegistryObject<MobBucketItem> EEL_BUCKET =
ITEMS.register("eel_bucket", () -> new MobBucketItem(EntityInit.EEL.get(), Fluids.WATER, SoundEvents.BUCKET_EMPTY_FISH, new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_MISC)));
}
I would really appreciate some help on this. Please let me know if I need to provide anything else. Thank you.

Your entity will load after your item. So EntityInit.EEL is not loaded. You should not use RegistryObject for your entity, but you can directly instantiate it instead.
For example:
public static final EntityType<Entity> FOO = EntityType.Builder.of(...)

Before beginning, it would be beneficial to those wishing to assist you if you were to mention the version of Forge that you are targeting. That said, as it appears you are using DeferredRegistry and RegistryObject to register your entities, etc, I believe that the following information will be correct for your version.
The problem that is occurring, is that the deferred registration is attempting to eagerly construct MobBucketItem when it is time to register your bucket item. As Items are registered before Entities, this leads to the RegistryObject for EntityInit.EEL being empty, hence calling get() crashing the mod loading process.
The solution is to use the MobBucketItem's other constructor, which takes a supplier to the entity as its first argument and not an EntityType. A Supplier is either a class that implements the supplier interface, or a lambda that returns a value of the form () -> value. This will look familiar as that is how you provide the value to return to the registry once Forge begins building the Item Registry
public static final RegistryObject<MobBucketItem> EEL_BUCKET =
ITEMS.register("eel_bucket", () -> new MobBucketItem(() -> EntityInit.EEL.get(), () -> Fluids.WATER, ()-> SoundEvents.BUCKET_EMPTY_FISH, new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_MISC)));
Internally, Forge deprecates the constructor you were using to make the MobBucketItem and wraps the first 3 arguments in suppliers, then calls the form of the constructor which accepts those suppliers. This is specifically to allow the use of modded entities, fluids, and sounds, even if their registries haven't been built yet.
So to wrap up, take the first three arguments you were previously passing into the constructor, and turn them into suppliers. If that version of the constructor does not exist in the version of Forge you are targeting, then I recommend updating your version of Forge to one that does provide that overload.

Related

Modifying final static variable within final public class Java

I have a quick question regarding modifying a final public class. Based on some researches, it seems like final public class cannot be inherited or implemented. My goal is to change one final static variable within this final public class.
class name is: public final class Utils
private static final Set<String> DISALLOWED_HEADERS_SET = Set.of(
"authorization", "connection", "cookie", "content-length",
"date", "expect", "from", "host", "origin", "proxy-authorization",
"referer", "user-agent", "upgrade", "via", "warning");
I want to get rid of authorization field from this DISALLOWED_HEADERS_SET. Is there any ways to doing this?
I heard reflection is one way to modify classes. This is a Apress/java-9-revealed to a github that seems to reveal what's inside of the class
This thread (question) has been identified as XY problem. I will try to explain with more information on why I want a solution for the above problem. Before digging into the reason that drove me to ask this question, I will cover the current situation of where this problem is at as of now.
It is important to understand that this problem has been already posed by Clevertap to Oracle. If you follow Oracle link, you can see that this problem has been acknowledged and updated to Jdk 11. Hopefully, Oracle applies this fixed source code to the coming Java 10, but it is highly unlikely given the fact that Jdk 9 represents Java 9. This being said, only solution there is to use reflection which the open thread in clevertap suggests.
Now, I will briefly explain what I have achieved and am trying to figure out. I have been working on a framework that I have been developing for sending Push Notification to APNs using Java language. Everything works except one functionality.
[I will share this framework through GitHub in the near future for those trying to send notification to APNs without depending on third party frameworks, such as Jetty, Netty, or okhttp.]
The problem rises when I try to use token as a way of authentication to send notification. I have successfully created token following through the instruction provided by Apple. All I have to do is to set request header with authorization key and bearer <token> value. However, when I use .setHeader derived from jdk9.incubator.httpclient module to set these values, it automatically omits this field. As aforementioned, authorization is part of DISALLOWED_HEADERS_SET and it is clearly not allowed. If a user attempts to set "authorization" as a key value for the request header field, it is deleted. If you have any suggestions to work around this problem. It will be awesome and helpful for others facing the same problem.
Bad news folks... jdk 9.0.4 removed setSystemHeader method, so if you want to use reflection, you need to use Jdk 9.0.1
As promised before, I created java library for sending notification using pure java code and pushed it to the github. I used older version that was based on jdk10 for my published app. Older version only supported tls connection. Now the current version based on jdk11 is supporting both tls and token based authentication for sending push notification to APNs.
Will just removing that value from the set work for you? Something like this:
Field f = Utils.class.getDeclaredField("DISALLOWED_HEADERS_SET");
f.setAccessible(true);
#SuppressWarnings("unchecked")
Set<String> headers = (Set<String>)f.get(null);
headers.remove("authorization");
There is no clear for me what are you going achieve by inheritance since this value is static.
But if you possible to recompile your application, have you considered of object composition? This can be an alternate to inheritance and is often used to simulate polymorphic behavior in case of final class or 'multiply' inheritance.
If you can 'inject' the new class instead of original one (which is final), you can compose a new class that contains instance of final class and delegates its methods to them. There is no need to create same final static variable.
If you wish to bank upon reflection, this might help -
Class reqClz = request.getClass();
Method setHeaderMethod = reqClz.getDeclaredMethod("setSystemHeader", String.class, String.class);
setHeaderMethod.setAccessible(true);
setHeaderMethod.invoke(request, "authorization", "<token>");
for which you might have to open the incubator module's package with the use of VM arg:-
--add-opens jdk.incubator.httpclient/jdk.incubator.http=<your-package x.y.z>
OR
Was also thinking that, another way here possibly could be patch the module content
--patch-module <module>=<file>(<pathsep><file>)*
for the jdk.incubator.http.internal.common.Utils class but as recommended not more than testing or debugging purpose.
The following code allows you to change the value of private static fields (non-final):
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class SetFinalField {
#SuppressWarnings("unchecked")
public final static void main(String[] args) throws Exception {
System.out.println("elements before: " + SetTarget.DISALLOWED_HEADERS_SET);
Field f = SetTarget.class.getDeclaredField("DISALLOWED_HEADERS_SET");
f.setAccessible(true);
ArrayList<String> l = new ArrayList<String>();
l.addAll((Set<String>) f.get(null));
l.remove("authorization");
HashSet<String> hs = new HashSet<>();
hs.addAll(l);
f.set(null, Collections.unmodifiableSet(hs));
System.out.println("elements after: " + SetTarget.DISALLOWED_HEADERS_SET);
}
public final static class SetTarget {
private static Set<String> DISALLOWED_HEADERS_SET;
static {
HashSet<String> l = new HashSet<>();
Collections.addAll(l, new String[]{"authorization", "connection", "cookie", "content-length",
"date", "expect", "from", "host", "origin", "proxy-authorization",
"referer", "user-agent", "upgrade", "via", "warning"});
DISALLOWED_HEADERS_SET = Collections.unmodifiableSet(l);
}
}
}
If you change the field to final this will be prevented, so to answer your question: It's not possible to do what you currently try to do using reflection. There is a way, though by using JNI, but you don't want to go that way. Whatever you try to accomplish you should try to find a different solution, e.g. by checking the class that is using this header if it can be configured with an alternate set of disallowed header values or go the way #nullpointer described.

Create modules Java

I have a Java bot running based on the PircBotX framework. An IRC bot simply replies on commands. So now I have a list of static strings e.g.; !weather, !lastseen and the likes in my Main.java file.
For each command I add I create a new static string and I compare each incoming message if it starts with any of the defined commands.
Pseudocode
Receive message `m`
if m matches !x
-> do handleX()
if m matches !y
-> do handleY()
This is basicly a very large if test.
What I would like to do is create some sort of skeleton class that perhaps implements an interface and defines on which command it should act and a body that defines the code it should execute. Something I'm thinking of is shown below:
public class XkcdHandler implements CommandHandlerInterface
{
public String getCommand()
{
return "!xkcd";
}
public void HandleCommand(String[] args, Channel ircChannel)
{
// Get XKCD..
ircChannel.send("The XKCD for today is ..");
}
}
With such a class I could simply add a new class and be done with it. Now I have to add the command, add the if test in the list, and add the method to the Main.java class. It is just not a nice example of software architecture.
Is there a way that I could create something that automatically loads these classes (or instances of those classes), and then just call something like invokeMatchingCommand()? This code could then iterate a list of loaded commands and invoke HandleCommand on the matching instance.
Update
With the answer of BalckEye in mind I figured I could load all classes that are found in a package (i.e., Modules), instantiate them and store them in a list. This way I could handle each message as shown in his answer (i.e., iterate the list and execute the class method for each matching command).
However, it seems, according to this thread, that it's not really viable to do. At this point I'm having a look at classloaders, perhaps that would be a viable solution.
There are several ways I think. You can just use a Map with the command as the key and an interface which executes your code as the value. Something like this:
Map<String, CommandInterface> commands = new ....
and then use the map like this:
CommandInterface cmd = commands.get(command);
if(cmd != null) {
cmd.execute();
}
You are looking for the static block, for instance:
class main {
private static List<CommandHandlerInterface> modules = new ArrayList<...>();
static { // gets called when a static member gets accessed for the first time (once per class)
modules.add(new WeatherCommand());
// etc.
}
// method here which iterates over modules and checks
}

GWT.create(clazz) "generics" approach

I have to develop an "generic" wigdet for a GWT/GXT project and to do so I need to create an instance of an object which type is unknown. I found an approach that works perfectly in dev mode but as soon as I try to compile my project and deploy it I get an Only class literals may be used as arguments to GWT.create() error.
Here is a sample of what I do:
public class GenericEditableGrid<M> extends Grid<M>{
private final ToolBar toolBar = new ToolBar();
private final TextButton newItemButton = new TextButton();
protected GridInlineEditing<M> editing;
private final Class<M> clazzM;
public GenericEditableGrid(Class<M> parametrizedClass, String gridTitle, ListStore<M> listStore, ColumnModel<M> cm) {
super(listStore, cm);
clazzM = parametrizedClass;
// ... then I create my widget
bind();
}
private void bind(){
newItemButton.addSelectHandler(new SelectEvent.SelectHandler() {
#Override
public void onSelect(SelectEvent selectEvent) {
editing.cancelEditing();
// it is the folliwing line which is the problem obviously
M element = GWT.create(clazzM);
getStore().add(0, element);
int index = 0;
editing.startEditing(new Grid.GridCell(getStore().indexOf(element), index));
}
});
}
}
And this is how I use it in my subclasses:
super(InternationalString.class, gridTitle, new ListStore<InternationalString>(isprops.key()), buildColumnModel());
Basically, I would like to know what the problem is exactly with this approach and eventually how I should do to make it well.
Please note that my concern is not just to make it work, but more to do it the right way. As I could just avoid the problem using an abstract method which would handle the GWT.create() method in the daughter classes. But this is not the design I want, it just doesn't look right.
What I don't get also is what's the difference between doing this:
MyClass e = GWT.create(MyClass.class);
and:
Class<MyClass> clazz=MyClass.class;
MyClass e = GWT.create(clazz);
Because as far as I am concerned I think this is basically what I am doing and it looks like the same thing. Isn't it?
There's a well-worded explanation in this forum:
As the error message indicates, only class literals may be passed to the GWT.create method. The reason for this is that all GWT.create calls are basically turned into constructors at compile time, using the deferred binding rules for your module. As a result, all classes must be decided at compile time - your code requires that the at runtime the class is decided. This is too late, and so cannot be compiled.
GWT is not proper java, and so cannot be always treated as java. This is one such example of things that cannot be done in gwt. ...
What is it you are trying to do? Either you are making it far more complicated than it needs to be, or you need to write a generator to do it instead of taking this approach.

Compilation error: method render in class list cannot be applied to given types;

I'm still learning Play!Framework and, as a lesson, I decided to include a new feature in a application (available in Samples, called "Computer Database").
Well this app is very simple. It has a Computer model and it has a #ManyToOne relationship with a Company model. Well, basically I decided to copy Computer model and I made a Employee model, which is basically the same. I copied Computer Model, Controller and Routes and I tried to compile unsuccessfully, as you can see below:
public static Result list(int page, String sortBy, String order, String filter) {
return ok(
list.render( //-- LINE IN RED!
Employee.page(page, 10, sortBy, order, filter),
sortBy, order, filter
)
);
}
Actually, I tried to compile it because I was looking for more tips, as I have other issues in my Eclipse, only in my new Controller, called "Employees". The code above is marked with:
Multiple markers at this line: Occurrence of 'render'; The method render(Page<Computer>, String, String, String) in the type list is not applicable for the arguments (Page<Employee>, String, String, String)
And only in this controller I have static methods Result update/create/save/delete pointed with a message:
The method render(Form < Computer >) in the type createForm is not applicable for the arguments (Form < Employee >)
The point is: I'm not trying to use this method with Employee obj arguments. Every single method contains: Form< Employee > employeeForm = form(Employee.class)...
My IDE is saying this method render is not applicable for the Employee Page's arguments, only for Computer Page's, which sounds totally weird for me, because, as I said, it is a generic class, a play-framework native class, and Employee and Computer are models created by me.
--
Employee.page's signature:
public static Page< Employee > page(int page, int pageSize, String sortBy, String order, String filter)
--
I searched a dependency/library inconsistency, but personally I could find it. I've already tried to restart Eclipse, my server, "play clean"/"update"/etc in the console... What else could I verify?
We solved my issue. We simply replace the code like list.render for a previously ready code called listEmployees.render and then we did the same for public static Result save and public static Result create, and in this case, for its corresponding createEmployeeForm, which was also previously done. But we were not using the Employees' views originally developed for this, because our great Eclipse IDE was pointing issues.
We simply ignored this Eclipse issue and, voilĂ , it runs! Then we refreshed the project and now it's right. Thanks for all attention!

Using Stripes, what is the best pattern for Show/Update/etc Action Beans?

I have been wrestling with this problem for a while. I would like to use the same Stripes ActionBean for show and update actions. However, I have not been able to figure out how to do this in a clean way that allows reliable binding, validation, and verification of object ownership by the current user.
For example, lets say our action bean takes a postingId. The posting belongs to a user, which is logged in. We might have something like this:
#UrlBinding("/posting/{postingId}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
Now, for the show action, we could define:
private int postingId; // assume the parameter in #UrlBinding above was renamed
private Posting posting;
And now use #After(stages = LifecycleStage.BindingAndValidation) to fetch the Posting. Our #After function can verify that the currently logged in user owns the posting. We must use #After, not #Before, because the postingId won't have been bound to the parameter before hand.
However, for an update function, you want to bind the Posting object to the Posting variable using #Before, not #After, so that the returned form entries get applied on top of the existing Posting object, instead of onto an empty stub.
A custom TypeConverter<T> would work well here, but because the session isn't available from the TypeConverter interface, its difficult to validate ownership of the object during binding.
The only solution I can see is to use two separate action beans, one for show, and one for update. If you do this however, the <stripes:form> tag and its downstream tags won't correctly populate the values of the form, because the beanclass or action tags must map back to the same ActionBean.
As far as I can see, the Stripes model only holds together when manipulating simple (none POJO) parameters. In any other case, you seem to run into a catch-22 of binding your object from your data store and overwriting it with updates sent from the client.
I've got to be missing something. What is the best practice from experienced Stripes users?
In my opinion, authorisation is orthogonal to object hydration. By this, I mean that you should separate the concerns of object hydration (in this case, using a postingId and turning it into a Posting) away from determining whether a user has authorisation to perform operations on that object (like show, update, delete, etc.,).
For object hydration, I use a TypeConverter<T>, and I hydrate the object without regard to the session user. Then inside my ActionBean I have a guard around the setter, thus...
public void setPosting(Posting posting) {
if (accessible(posting)) this.posting = posting;
}
where accessible(posting) looks something like this...
private boolean accessible(Posting posting) {
return authorisationChecker.isAuthorised(whoAmI(), posting);
}
Then your show() event method would look like this...
public Resolution show() {
if (posting == null) return NOT_FOUND;
return new ForwardResolution("/WEB-INF/jsp/posting.jsp");
}
Separately, when I use Stripes I often have multiple events (like "show", or "update") within the same Stripes ActionBean. For me it makes sense to group operations (verbs) around a related noun.
Using clean URLs, your ActionBean annotations would look like this...
#UrlBinding("/posting/{$event}/{posting}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
...where {$event} is the name of your event method (i.e. "show" or "update"). Note that I am using {posting}, and not {postingId}.
For completeness, here is what your update() event method might look like...
public Resolution update() {
if (posting == null) throw new UnauthorisedAccessException();
postingService.saveOrUpdate(posting);
message("posting.save.confirmation");
return new RedirectResolution(PostingsAction.class);
}

Categories

Resources