#development
1 messages · Page 62 of 1
the difference is that how the annotation interface is declared would be different - as it would have different targets
a METHOD? how can a method be nullable?
this could make a legitimate difference if you had an annotation processor
same way fields can be
why don't you understand that this is how annotations worked before TYPE_USE was introduced
as in the return value is nullable
oh wait do you mean ElementType.TYPE and ElementType.PARAMETER?
so you think that @NotNull is there to say "yes lol although this method obviously exists, here I am again, the @NotNull annotation, to assure you, that this method does exist"???
this makes little sense imho?
clearly not what i said
bruh
we already have an annotated return value, so what's the difference between annotating the return value, and annotating the method itself?
return value & method are the same thing, that's not the thing that causes 2 annotations
it's method/return value & type
with using an annotation that applies to both METHOD and TYPE_USE, you indicate that you want to annotate the return type and the method
how is this so difficult to understand?
I know what's causing these broken javadocs
yep it's "intended" behaviour
then outside of html workarounds, what fix do you suggest?
what's your point then
given that this isnt a bug
at best it's java lacking a way of disambiguating annotations
you want to fix perfectly reasonable functionality
my point is that just because something is like it is, doesn't mean it's correct
oh so you want to change how annotations work?
So if something is working as intended it isn't correct?
you could say that the javadocs have an ambiguity issue
it's not a jd issue
obviously I want to change how the generated javadocs look like
well, the solution is to use jspecify :)
Okay, let me ask you, you have a list of method annotations and a list of type_use annotations, how do you display them?
sort of
but I mean they could say like ```
Method annotation: @NotNull
etc...
that'd just be verbose and ugly
you'd have to rework the whole jd format to make that work i think
show some source code please, otherwise I have no clue what your TYPE_USE annotation is annotating
I'm not saying that you should do that
I'm saying that the issue could be like 50% fixed with javadocs, and the other 50% with java itself (?), or jetbrains annotations
it is not a javadoc issue
in any case, this does not mean a published javadoc is broken
or a jb annotation issue
you can all enjoy your NotNull NotNull javadocs if you want to. Imho it's bullshit
the only "issue" is like i said, java having no way of disambiguating it like kotlin does with @field:NotNull or whatever
There is no source code, you are creating javadocs, all you have is the context it was given, a list of annotations with target METHOD and a lost of annotations with target TYPE_USE, some annotations target both
You have to display them with context, how do you do it?
I'm still waiting for actual source code which SHOULD result in javadocs actually showing different annotations for the method itself and its return type
https://github.com/JetBrains/java-annotations/blob/master/common/src/main/java/org/jetbrains/annotations/NotNull.java#L29
if they had an annotation for each target, this wouldn't be happening, no?
obviously that's not ideal
but I'm saying that it could be prevented with jb annotations
or maybe theres an even better alternative
ping me pls if someone finds any, until then I'm going outside and have a smoke lol
sure, but then youve got a whole new issue of 2 annotations to do the same thing
& have broken all backwards compatibility ofc
well you theoretically only need TYPE_USE for that nowadays
if you remove backwards compatibility
true
ah ok
so it can be fixed with jb annotations
if you remove the backwards compatibility factor
that's what I was trying to say
and so that would probably mean that it can't be fixed from java's side
i dont really know what this means but
it just depends on the target
your code for the method looks like you wanted to annotate the return value, and not the "method itself" right?
I know what you people are trying to say, e.g. "yeah it refers to both, the method and the return value" but have you ever seen a method IN REAL LIFE where the return value is a Nullable String but the method itself claims to return NOTNULL?
idk maybe I'm stupid, but I don't understand the difference
a method makes a contract through the NotNull annotation, which is "I will return something that's def not null"
even if the type itself could be annotated, it would either also be NotNull or Nullable, depending on what the method is annotated with
it's totally ambiguous
it's redundant
If anyone can give me an example of a method where the method itself is NotNull or Nullable, but the return type is the opposite, then I will maybe understand it
that wouldn't make much sense I guess
no, but thats not the point. in the (non)null case, there is no difference but there could be a legitimate difference for another (contrived) annotation, or with an annotation processor
(as basically all you're saying)
exactly, and hence I think that having the annotations twice in the javadocs makes no sense too
that's a good question.
I have right now only thought about Nullable and NotNull
both answers are bad for what it's worth
well you think that, but the java specification tells you clearly that the annotation applies to both the declaration context and the type context, and visualizing that might make sense in the Javadoc
idk why you guys (or girls) pretend to be that it 100% makes sense to have double annotations. I mean, ok, I get it, let's be real: Please ONLY thinkg about NotNull and Nullable right now. Look at this code:
@NotNull
public static List<@NotNull String> apply(@NotNull List<@NotNull String> strings, @Nullable OfflinePlayer player) {
and look at these generated docs:
Now check the parameter list
what is the first NotNull for "strings" referring to
it basically comes down to "what do we want to achieve with javadoc" and that's something we can think about, but that doesn't make the current javadocs "broken"
and what is the second NotNull for "strings" referring to?
it makes conceptual sense even if practically it doesn't
the parameter
type & parameter, i've said this multiple times already
yes sure, if you think like javadoc.exe it makes perfect sense, but javadocs are meant for humans to look at
I don't understand this, can you maybe explain this to me?
humans yes, specifically programmers, who should be able to recognise why this is happening
Although it seems like I'm trying to fight, that's not true. I'm trying to learn new things
there are many things that could be changed in javadoc because it is meant for humans to look at
bro you said you understand it
maybe I was wrong then, stuff happens
one of them is for the Type, as in List. it's "redundant" in this case but it's not always
the other is for the parameter itself
Please explain to me in which situation the returned value is NotNull while the type might be nullable
how would that even be possible?
the returned TYPE is always NotNull, otherwise the method would be using void
i've already responded to that
that's my understanding
thats not true but
that's not how Java works
are you familiar with the concept of type aliases?
I am not
java doesnt have them but other languages do
ok well the gist is it's just a "variable" for a type
java is basically the only language I know well
in kotlin for example i could write typealias SmallNumber = Int and then whenever I write SmallNumber it's the same as writing Int
well but that's what we call generics, and the javadocs of what I sent above is obviously not generic
ok, let's turn the question around, lemme give another example
it's just to save writing long types usually
You see this. You want to use this method. Do you have any advantage of being able to see the duplicated NotNull annotation on the "strings" or "player" param?
suppose java had these, we could write something like typealias OptionalInt = @Nullable Integer
now let's say we write a method void acceptOptInt(@Nullable OptionalInt). would you expect to see the double annotations in this case?
i've already said multiple times, it's redundant in this scenario but there are situations where it could be legitimately important
it's not about having any advantage
yes in that case, it'd make much sense, but since java doesn't have that feature, it makes little sense to talk about it ig?
There is no advantage but no disadvantage either
I wonder what the difference is. The second NotNull is referring to List<@NotNull String> - but what does the first @NotNull refer to?
@NotNull List<...>
@NotNull strings
yeah both doesn't make sense, pls include the var names too
Targeting the parameter and the parameter type
yes, but the annotation was defined to apply to both the parameter and the type
but a type cannot ever be nullable in a method signature nor as a return value
so why would it not behave the way it was intended to
I guess a good way to visualize would be (@NotNull (@NotNull Type) name)
i was just about to write that lol
great minds
yeah just apply parens and the difference is clear
you clearly don't understand type annotations
what's that? Is that supposed to be a part of a method signature?=
What? It's a parameter
void doSomething(@NotNull (@NotNull Type) name) {}
maybe you could help me understand them
bro this is so circular
This conversation has been going for like 1 hour, if you haven't understood it yet then oh boy
"why does it annotate twice?"
"this is why"
"i understand that but it doesnt make sense"
"yes it does for the same reason"
"yes but [incorrect explanation of how things work]"
repeat 20+ times
I read that many times already
which part do you not understand about it then?
Wait until you see something like @NotNull Object @NotNull ... objects
@NotNull Blah @NotNull[] 😋
do you claim that a method signature like this'd be valid?
public (@NotNull (@NotNull Type) name) Type name() {
clearly not
in Java? no, but no one said that
that's what I thought too.
so again, what's your point
it was explicitly stated to just be a way of visualising the difference
anyway
here's the part of the specification you're looking for
works as intended, case closed
public (@NotNull (@NotNull String) name)()
Ok I repeat this again: A Function/Method in Java needs to have exactly one return type. And each parameter also has to have one type. and neither of those TYPES itself can be nullable
You cannot declare a method that has a null return type or a null parameter type
so having a duplicated NotNull makes no sense whatsoever
holy shit
literally nobody is saying that
The JLS is saying that?
you ALWAYS annotate types to be nullable or nonnull
also yeah
it doesn't make sense to say "this method is nullable"
it doesnt mean that the Integer class suddenly becomes null
it just means that its set of values includes null
yeah but "this methods returns null or <whatever>"
to be fair im gonna be charitable, the nonnull/nullable example is not a great way of explaining this because theyre one of the few annotations with semantic meaning
yes, that's why you annotate the return TYPE to include null
if we were just using some arbitrary A and B this conversation would've ended ages ago
@Nullable
public String getNameOrNothing() { ... }
the annotation isn't called @ReturnsNull
In this case, Nullable obviously refers to the return value, not the return TYPE
please just stop talking
fun fact but types and values are actually quite strongly linked
theyre not (in java at least) totally separate entities
You're looking at all annotations from the perspective of the nullable/notnull annotation ..
yeah like i said
Im trying to learn things here, not to cause anger or sth lol.
yes, that's true, because those are the only ones I care about right now
if not, why not?
well tbf it makes no sense at all, neither A nor B nor Foo is declared?!
...
ofc we can discuss theory but what's the point?
you annotate the return TYPE, because you want to tell the developer "the return TYPE is String + the null value"
@NotNull String blah
AHHHHH NotNull or String isnt declared AAAAAAAA
how you sound rn
I'm looking at javadocs as a human being and don't care about the theory that is behind them generating it
then you are doomed to just be eternally wrong
I want to know if I may pass null as a parameter, or not
you mean as an argument?
I want to know if this method returns a String, or if it might return null too
there is a legitimate reason for the annotations to be duplicated whether you want to learn it or not
I didn't study computer science or anything and I don't really care about the theory behind it, in fact I studied law and am a tax lawyer, but who cares, that's not the point. My point is that if I read javadocs, I want to know whether I can use Null as parameter, or not. And Whether this method returns null sometimes, or never. And I don't care how it internally works. And I'm pretty sure that 99% of people who look at javadocs agree with me that seeing @NotNull @NotNull isn't going to help them more than a single @NotNull would have done

And I'm pretty sure that 99% of people who look at javadocs agree with me that seeing @NotNull @NotNull isn't going to help them more than a single @NotNull would have done
yes, but that doesn't mean it's broken
there is 0% of situations where a method's return value would be nullable if the return type itself is marked with @NotNull, and vice versa
and same thing applies to method parameters
and even less something that needs to be fixed right now
i believe this is called a motte and bailey fallacy 🤓 👆
I give you that, maybe it's not broken, but it's definitely at least slightly confusing - after all javadocs are meant to be read by people
yo has this conversation gone anywhere
and not by machines
not at all lmao
Never will
okay ill be back in 3 hours
nah we'll end it right now. seems like we just have different opinions or I'm too stupid to understand their arguments
both is possible
i wont be back in 3 hours
after snacking 7 2mg xanax
i mean i tried many times to legitimately explain it but then you pulled shit like this so...
cant have it both ways man
that's what I was saying from the beginning basically
yep
I do understand that it DOES make sense for XYZ annotations, but I was specifically talking about Nullable and NotNull
why should they be any different
that were the only annotations I was talking about, maybe I should have clarified that
because if method X returns a "String" or a "@NotNull String", in both cases the method itself can't possibly annotated with "@eager saddleable"
oh sry for ping
classic
F for null
idk if it's been mentioned before but it's from ElementType
TYPE_USE is from "only" java 8
so that's why jb annotations has a whole bunch
you might be 100% correct on that, I don't know, all I care is that I wanna read javadocs like a normal human being and see "does this method always return something, or can it also return null"
and what I see is that it returns "@eager saddleable @eager saddleable String"
So the logical consequence is that it returns a "nullable string or null" and going one leverl further you'll end up with seeing "it returns a string or null or null"
F x3
Null should just change his name
he doesn't talk here anyways
so
¯_(ツ)_/¯
been in here for over a year and not even a single message 💀
Unions of sets are idempotent so 🤓🤓
Double nullable does the same thing as single nullable, in layman’s terms
that's why there's double annotations
and it can be fixed: https://github.com/jspecify/jspecify/blob/main/src/main/java/org/jspecify/annotations/NonNull.java#L99 but that removes java 7 and below compatibility
yeah I know that that's the technical cause for this. I still think that it's a javadoc.exe issue as it should detect that the "return value" is nullable and not the "type of the return vaue", it's obious to me
but after all, I haven'T studied CS or anything, maybe I am missing an important point, that might be possible ofc
no ur mixing it up with params
gimme a min
ok
the return value does not exist in the source, and also not in the javadoc
you can't annotate values in java
ofc the "value" does not exist, I'm not totally stupid. but the type eixsts
and e.g. a String is either always a String or it can be nullable
why are you saying confusing things then
how can you return someting if the return type itself is nullable`?
exactly. so One @eager saddleable would be enougn to show that
sorry Null dude, please change your name lol
how is that relevant to the amounts of nullables in the text
it's a javadoc.exe issue as it should detect that the "return value" is nullable and not the "type of the return vaue"
I do understand that it DOES make sense for XYZ annotations, but I was specifically talking about Nullable and NotNull
so you're suggesting that javadoc should track all nullity annotations internally specifically to avoid this only for nullity annotations?
for the 2 @NotNulls in the beginning, the first one refers to the method
For example, @Pure could define a pure method (ignoring that contract exists)
the second one refers to the return value
For example, @Nullable could define a nullable parameter
Why does JetBrains Annotations have the first one? Because of java 7 and below (ex jspecify does not support java 7 and below in order to prevent this issue)
Why does JetBrains Annotations have the second one? Because that's technically the correct one to use
Because JB Annotations has both, that's why there's a duplicate, and that's also why javadoc doesn't remove the duplicate
For the parameters, it could be thought of similarly, although it's not as clear
@light pendant
¯_(ツ)_/¯
yes. and for NotNull too, ofc
ha
well but that's not the case, we don't need to discuss irrelevant things
that's great if jspecify solves this issue. but I only came up with this issue because I'm using jetbrains annot and that's what paper uses too, and their javadocs look messed upi
I thought you were the one that said having null safety was dumb 
then don't use paper javadoc
@light pendant this explains why it's not javadoc.exe's fault!!
Did I say that? If yes, I probably didn't specify it propertly. I think a method is fine to claim "My name is method() and I take in a String and I return either a String or null" and the code for that method should look like this imho
@Nullable public String method(@Nullable String something)
They should make a new language without null values and without annotations and instead of javadoc you call it haddock and it works perfectly without any ambiguity or errors ever
and of course it must be very easy for people without a cs background to understand, with no terminology based on complex theory at all
whats a monad
Creates a null raw pointer.
uhhhhhhhhhhhhhhhh
yes, I understand that. But can't javadoc.exe understand that if the annotation was already "used up" by the return type, that it cannot possibly still apply to the method itself? How can ANY method be nullible? it's a method. It's declared. The method itself cannot be null
See I can get away with things like this because redempt isn’t here to call me out
brb I gotta drain my AC otherwise I'll die
because some things might apply to both the method and the return type
There's other annotations other than @Nullable that might be more clear
it can be "used" again, that's the thing,
the most bizarre shit you've said today is that javadoc should specifically avoid that for nullity annotations but not for any other in existence
not all annotations are treated equally I suppose
well, apart from that "internal paper rule" that tells us to avoid PRing upstream 
We almost reached that conclusion earlier lol
I already mentioned many times that I am specifically only worried about NotNull / Nullable
is it not true? how else could you explain that 99% of paper API never got added to spigot?
okay so the javadoc program should have a hardcoded special case for a random third party annotation
multiple even, there are a few libraries providing nullity annotations
I suggest you stop pulling shit out of your ass
I want my library added too, please
me too
but because it's shorter, it uses @N and @DN
this is getting complicated, maybe we should introduce a new annotation @DoesNotRepeatWhenAppliedToTypeUseAndMethodOrParameterOrField
no, ofc not. there should be a builtin annotation, like java.lang.NotNull
lol
or similar to kotlin, an actual language feature for that
ok so this annotation only applies to rendered javadocs, right?
although I did hate on kotlin at first, I meanwhile understand that it makes sense
javax.annotation would like a word
I'd suggest to keep discussions objectively, without insulting anyone, thanks
as said, everyone's free to disagree with my opinions
says "people with cancer are broken"
I never said that. I used that phrase to show how an opinion that someone stated can lead to stupid assumptions
you heavily implied it
ok maybe I did. that was not intended. I severely apologize for that, fr I didn't mean it like that
my best friend's mother was diagnosed with breast cancer yesterday so yeah I really don't wanted to joke around about people having cancer. if any of my messages implied otherwise, I'm very sorry, it really wasn''t my intention
if java'd have a @FUck annotation, I'd apply it to cancer and I wouldn't complain if javadoc would duplicate that annotation
alright, i suppose this is over now, I got places to go
I wish you a wonderful day, have fun whatever you do emily ❤️
I still think that having NotNull twice in every method's signature is just annoying
sorry to hear about your friend's mother
I might be missing something but is there any reason why the while loop is never broken?
private String readIncoming() {
ConsoleFeed.log("Reading incoming...");
BufferedReader inputReader = new BufferedReader(new InputStreamReader(inputStream));
try {
String retrieved = null, input = null;
while((input = inputReader.readLine()) != null && !input.isEmpty() && !input.isBlank()) {
ConsoleFeed.log("Input: "+input);
retrieved = retrieved == null ? ""+input : retrieved+input;
ConsoleFeed.log("Retrieved: "+retrieved);
}
ConsoleFeed.log("Passed reading loop...");
inputReader.close();
return retrieved;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
```I get output in console but it never reaches `Passed reading loop...`
`isEmpty` and `isBlank` are just there for testing.
thanks, I hope she'll be fine. IIRC breast cancer is the "best" cancer one can have, idk. you know what I mean
it should break out just fine? Maybe add some debug output (Plugin#getLogger() or System.out.println()) and check what it actually reads and where it's stuck?
you should also be using a trywithresources
instead of just caling .close() at the end
you know, I have kinda strated to like kotlin A BIT
it's still a huge issue that most of its features are located in the arbitrary kotlin-stdlib
but as we talked about all these nullabilty annotation stuff earlier, I'm now pretty sure that having ? and !! is a good lang feature
just for the record: I used to hate on kotlin very much earlier (I still hate many things about it, e.g. the ambigiuaty in using getter/setters vs actual field access) but yeah it does have some nice features, can't deny that
Why don't u like properties D:
They're awesome
No !! allowed
Tbf!! Can be better if you're lazy
Not good
But
Better than some other alternatives
does it get to the loop or is it perhaps stuck on reading the stream?
what output do you get exactly?
imagine this (gimme a sec)
public class Person {
public int age; // Yeah I know, it shouldnt be public, but imagine it's from a library you gotta use, idk
public void setAge(int newAge) {
if(newAge >= 150) throw new PersonCannotBeThatOldException();
this.age = newAge;
}
}```
if you now do person.age = 200 in kotlin, you don't really know if you access the field direclty, or the setter
I know that it's a very specific situation that usually won't ever happen, but still it's annoying yk?
kotlin itself is a good language but I think they made some TERRIBLE design choices, one is using == for equals() (although ofc you can just prevent it using ===), another is the weird getter/setter thing, and the third one is extension functions
extension functions per se are not bad but sometimes they force you to use extension functions on classes where they could have just added that method natively to the class instead
It outputs the json text that I was expecting it just never breaks the while loop.
For the comment about .close() it doesn't even get that far as stated in the original message.
paste the output you get pls
[Info] Input: {"result":[[["mining.notify","6914a94f"]],"e65e0968",8],"id":1,"error":null}
[Info] Retrieved: {"result":[[["mining.notify","6914a94f"]],"e65e0968",8],"id":1,"error":null}
as you call getNextLine() or whatever in the while condition, it should properly show every line and then some time be done
Idk where your stream comes from, but my C trauma screams to me that the stream just doesnt terminate
@hoary scarab maybe im just stupid, but you could try this and see if it helps
for(int i = 0; i < 32 && ((input = inputReader.readLine()) != null && !input.isEmpty() && !input.isBlank()); i++) {
}
that's good actually, it encapsulates more AND is more concise
curious why you think == is bad, extension functions are always a bit controversial
That is not true, only if you look at it from the "eyes" of Java
In Kotlin person.age = 200 IS using the setter, you can't access the field directly
yup
explicit getter & setter methods are kinda just c++/java cope, very few other languages actually do it like that
And a lot of languages also do == and === instead of methods
Huh... String retrieved = null, input = null; is the cause...
Had to make it ```java
String retrieved = null;
String input = null;
🤷
lol
Can't use String retrieved, input = null; because then the use of retrieved complains about not being initialized.
well yeah that makes sense
but i have no idea why these 2 would be different
bizarre
Interesting
Wonder if its java 17?
breaking changes like this pretty much never happen
Just always declare fields in a new line and problem solved 😌

The one that worked for you won't even work for me lol
String test3 = "Test", test4 = "Test";
String retrieved = null, input = null;
Hi, anyone know how to parse relational placeholders with papi api, with only offlineplayers instead of players ?
Kotlin does not make the field public, and the user does not need to know if it is a field or property
Also what's bad about using == besides possible confusion when coming from java?
is there any way to play a sound only for 1 player?
Player#playSound
^^, reference equality is such a niche operation, I really can’t see why you’d miss it
Unless you disagree from a design philosophy for some reason
Can't think of a time I used it in the past like 2 years of coding
Me neither
Also what's bad about extension functions? If organized and used correctly
If there's other stuff then feel free to share as there might be alternate solutions etc
Also check out coroutines
You'll see something similar in many other languages too and so it's a good thing to learn
(and bc the feature itself is good)
Bro doesn't like qol
I mean, that kinda makes sense tho
String s1, s2 = s1 = "hi" 

what happens if you suddenly remove the setter?
remove how?
like, commenting them out in the source code
it will say it can not find a setter or smth like that
the kotlin code will still compbile but it'll use direct field accesses instead
no I don't think so
well it's true though
kotlin has many great fatures but unfortunately its "conciseness" causes it to just be a guessing game sometimes
literally no it's not
it still generates a setter method
even if that method just does this.blah = blah
and let's say it does behave that way, genuinely, why does it matter?
the same thing happens
You don't comment it out, if you turn it from var to val you get an error
That's it
If you remove the Java setter method Person#setAge from your Java code, you won't be able to use the Kotlin property syntax person.age = newValue to set the value of the property directly in Kotlin. The ability to set the property value using the = syntax relies on the presence of the setter method. Without the setter method, you will encounter a compilation error in Kotlin when trying to set the value in this way.
To allow Kotlin to set the property value using person.age = newValue, you must have a corresponding setter method in the Java code for the property.
var myProperty: String = "hello"
myProperty = "there"
val myProperty: String = "hello"
myProperty = "there" // Error
Oh you're talking about interop? Well, again, error lol
isn't person.age = newValue just a syntax sugar (or whatever you want to call it) for person.setAge(newValue)?
Literally the same as something.set() it'll error if set doesn't exist
When interoping yes, in Kotlin no
"when i make breaking changes in my java code, the kotlin code breaks. this is clearly a problem with kotlin"
yeah when using java code, idk how kotlin code works
Yeah, but the same way that when you change it in java
person.setAge(20); // Error method doesn't exist
Kotlin would
person.age = 20 // Error no setter found
as you would expect
to interoperate means to access java (or whatever else jvm language, idk) code with kotlin?
Yeah
aight
And also, Kotlin knows if it's setter or field directly
Color change and tooltip change
But you would hope you'd never be accessing the field directly
What does that contract mean?
that the method mutates the object
Receiver* 🤓
what i said isnt incorrect
just vague
🤓
so your use of "*" to indicate a correction is itself incorrect
sit down kid
Makes sense
yeah but "the object" could refer to anything so its kinda ambigious
like maybe its referring to the parameter
no
if that'd be true, then how would you actually change field values?
from what I know, kotlin arbitrarily decides whether to use the setter or the field directly
On kotlin code, yes ig
What? First of all, are you talking about Kotlin or when Kotlin is interoping?
But I don't think it is arbitrary, if there's a getter defined it will use it, at least thats what makes sense to me
var x: Int
set() {
print(value)
field = value
}```
I dont remember how you define a setter xd
That's correct, other than the indentation ;p
thats all you can get at 1am from mobile xD
Anyways I'll give two examples:
Without custom setter
class Person {
var age: Int = 20
fun test() {
age = 10 // age = 10
}
}
fun main() {
val person = Person()
person.age = 30 // setAge(30)
}
With custom setter
class Person {
var age: Int = 20
set(value) {
// Do something
field = value
}
fun test() {
age = 10 // setAge(10)
}
}
fun main() {
val person = Person()
person.age = 30 // setAge(30)
}
TLDR:
Default setter properties will use field access when accessed by the members, will use setter outside
Custom setter properties will always use setter
Again, this is a non issue, you don't care about the field ever, it's a property
Kinda obvious though, it feels like you override the default setter
I'm talking about kotlin interop with java
somePerson.age = 28
this should imho use the field directly
if it's public, it will
No, that's a setter if it's available
I was ab to say
yeah that makes sense
rather, if it's visible to the caller, it will
if it isn't, it'll use the setter, this isn't groovy 
You are probably mixing public java fields with kotlin fields (properties?)
If the field is public Kotlin won't interop it as a property
what if the setter is just called age(int) and not setAge(int) ?

Then it won't interop either
isn't there a proposal for that or something?
Again this isn't even a Kotlin issue, you're bringing Java into Kotlin lol
I think so yeah
well it's not very unusual to use java and kotlin together
But it is very unusual to have a public field lol
does it just consider any setX a setter, so you can do class.x = foo? Or it also checks if there is a field with the name of the setter? Id say the later
yes, that's true ofc
the whole discussion I started is more theoretical than having any practical issues
so don't use setters 🙂
mutability is too hard
but the setter might have aditional logic, e.g. checking if age >= max_age
Not even in theory it makes sense though you do know wether you're accessing a field or a setter
Matt answer so I can go to sleep 
yeah I should also go to sleep
yeah that's what I meant. you have no clue whether you call a setter or access the field directly, it depends on whether the setter has a "correct name" and/or whether the field is accessible
Pretty much yeah, they are thinking about doing similar to what Java beans do, so it associates the field with the method instead of basing it on the name
'Pretty much yeah' what, any method that starts with set is a setter?
What? On that example you can clearly see when it's a field lol
But again, you always just use the assign syntax unless it's not available
That is associated with a field
I can only see that from your comments
sleep well
One is red the other is pink lol
yeah but that's your IDE being fancy, imagine looking at just the source on a pastebin or sth
You assume it's a property like any sane person would
I don't want my coding language to assume anything though
No one goes "oh I wonder if this Kotlin code is actually referencing a Java public field"
idk the official java docs published by oracle disagree on that
Why would I care about the java docs when I am writting/reading Kotlin?
Stop looking at it through the Java perspective
I never said that you personally have to care about it
I could say the same: stop pretending that everyone uses only kotlin and ignore the fact that literally all libraries / APIs are written in java
and yes, I know, it's very rare that you have an accessible field that at the same time has a getter/setter, but still it might be possible and the weird way kotlin decides which one to use is, imho, random at best
the syntax for calling the setter and the syntax for accessing the field is the same
Any person using Kotlin will look at any interop done with Java through the perspective of Kotlin, like I said no sane person thinks like that
and ignore the fact that literally all libraries / APIs are written in java
lol
No, the syntax for setting a property is only one, there is no setter and there is no accessing the field
yeah idk why you always have to say that "every sane person" is of the same opinion that you are
If you can find one of those pls link it
there probably is none. it's, as already mentioned, just a theoritical thought
A theoretical thought that never happens lol
But also yes I work with Kotlin, none of my co-workers have this wacky thoughts because they aren't coding in Java, they just accept it's a different language and move on
So yes it is insane to think like that
Just like this conversation is insane too lol
idk maybe it's just me who's worked with actually insane people but I find this quite insulting that you call everyone insane who thinks different from you
and the argument "well my coworkers don't care about it, so it's not an issue" is a pretty bad argument imho
yeah anyway, let's just agree that we have different opinions on this, as discussing it further won't lead to any new conclusions anyway
I just find it weird that calling person.age= whatever does not directly show you whether it's a method call or not, and I find that stupid
imagine doing somePerson.age = -2
should throw an exception right?
nobody can be -2 years old
So then call the java method
(ok well usually a person shouldn't have an age field to begin with, but only a birthday)
Why? Why do you need to know
The user doesn't need to see
To see whether the setter's validation logic gets called
Kotlin usually thinks these things are up to the user
Like how the user doesn't need to see if the getter in setter in Java actually does anything
well the javadocs usually tell you which exactly the setter is checking
Anyways I'm busy so if u have questions that aren't being answered in a while u can ping me and I'll try and explain once I get on pc
but yeah as said, this discussion is leading nowhere, we just have different opinions on how a language should work, there's little point in discussing it any further.
Same thing can be said by setAge(-2), the javadocs will tell you it'll throw the same way that if you check the docs when doing age = -2 will tell you it
But anyways this is a waste of time, cya lol
TRUE
class Lol {
static int lmao;
static {
throw new RuntimeException("lmao is not allowed");
}
}
Lol.lmao = 3; // This throws an exception!! but how??? it's just field access
java has the exact same "problem" if you look hard enough. not quite the same thing ik, but this is indirectly calling a method. if you disagree with kotlin on that principle you should also disagree with static initialisers
also yes im a sucker for punishment so im reviving this conversation
out of curiosity, two things:
- python, c#, js/ts, and others also allow overriding getters & setters. do you disagree with it in principle, or just in kotlin?
- you never did say why you think
==for object equality is bad
I’ll kill you
Python, js, and ts have properties too? 😮
ts definitely does
pretty sure about the other two
js probably doesnt have it as an actual language feature but you can accomplish it with some hacks
stop
that wouldn't compile lol
it'd complain about "initializer must be able to complete normally" or sth like that
- python, c#, js/ts, and others also allow overriding getters & setters. do you disagree with it in principle, or just in kotlin?
I'm not sure what you mean with that. To me, a setter/getter is a just like any other method that you declare
- you never did say why you think == for object equality is bad
Yeah that's not bad, just gotta keep in mind that java's == is kotlin's ===
not it would not
overriding getters and setters as properties like kotlin does
is what i mean
ah mb, easy workaround tho ```java
static {
lol();
}
static void lol() {
throw new RuntimeException("lmao is not allowed");
}
yeah that'd work indeed lol
but I don't understand your point
ofc you'll get problems if you randomly throw exceptions in the static init block
that's why usually, people don't do it lol
this is what scientists don't want you to know
it's to show an inconsistency in your point
you claim that kt properties are bad because you wouldnt expect X.blah = blahblah to throw an exception
im showing that under the right circumstances the exact same thing can happen in java
wanna see something nasty?
ergo you either need to change your point or conclude that java has the same problem
ergo is big nerd word
I use this to avoid IJ claiming "the if(...) thingy is always true" lol
i know but it makes you feel so clever
i was almost tempted to say it again
isn't it basic knowledge after grade 6th?
still nerd word tho
true
the mount everest's height is 8848 meters btw
I also know nerd things
google sometimes claims it's more but I don't care what google says
well not really, the issue I talked about is that in kotlin, you don't know whether you call an input-validating setter, or not (if whatever you access is written in java)
in java you can see if you are setting a field with = or accessing a setter with methodName(...)
usually ofc you don't have public fields that aren't final, but what about protected fields
what about them?
the same issue?
in java you can see if you are setting a field with = or accessing a setter with methodName(...)
the natural follow up is "why is that a problem?"
seriously
so what?
why's it so bad
What does that do?
public class Person {
static int MAX_AGE = 150;
int age;
String name;
// Constructor that sets name and age
Person(...)
void setAge(int newAge) {
if(newAge > MAX_AGE) // throw exception
this.age = newAge;
}
}```
Now you extend this class from kotlin
```kt
class OldPerson: Person(age: Int)
val myGrandpa: OldPerson = OldPerson("Roman", 150)
myGrandpa.age = 151 // oh shit, he had birthday yesterday
does this throw an exception or not?
and yes, my grandpa was called roman, and no, he didn't actually live up to 150 years
i would guess yes, but also this is EXTREMELY contrived and almost never going to be a real "problem"
myGrandpa.setAge(151);
Does this throw an exception or not?
yes, sure
yes, sure. I said the whole time that my point is rather theoretical and not of any practical relevance
so you're complaining over nothing, basically
I'm not complaining about anything, I'm just wondering about design choices that could lead to issues
set and = are both just as ambiguous there
they're not as age is package-private and I was meant to call it from the same package or a derived class
i dont understand why anyone would think it doesnt call the setter
because the field is accessible
mfw im not complaining
how else would you access the field if every call to it is "overriden" with calling the setter
idk I know it's probably not a real-life issue, I just like to think about it from the theoretical perspective
If the filed is accessible it calls the field first
another weird thing is the extensive use of extension functions that kotlin DSL uses for their own classes, like why the hell is "all" on TaskProvider (or was it another class? I don't remember) an extension function if they could have added it to the class itself
yeah but is it accessible? that depends on in which package OldPerson is declared if it's a protected field
okay and so what
or am I confusing protected with package-private
There is no package-private in Kotlin
but Person is a java class
only OldPerson is a kotlin class
I can only repeat myself: I know that all my points are only issues in theory, but not in reality
i really dont get what point you're trying to make though
it's not an issue if the semantics are clearly defined somewhere, which they certainly are
at worst this just means some jr gets slightly confused and has to google something
but like...
they probably still dont know what static means sooo
jr?
junior
aah
true lol
really i just mean "idiot" in a more polite way
pebkac
calling people idiots just because they don't know something is indeed quite unpolite lol
I could call anyone here an idiot because they don't remember the conditions of § 985 BGB too
someone is not automatically an idiot just because they don't know a specific thing lol
hence why i didnt say that
the conditions of § 985 BGB are very interesting though. I'd happily explain them but I guess nobody except me cares about it lol
does anyone know of a reliable way to listen for when an Openable block is opened or closed, or at least a door or trapdoor? listening for PlayerInteractEvent sort of works but I have to manually check for a lot of conditions that could change between Minecraft versions myself and I have to listen for it being changed by redstone separately
There appears to be no other standard event to do so
IDK the exact event but maybe BlockStateEvent?
There doesn't seem to be any event for when a block state changes, I looked through everything in org.bukkit.event.block and tried listening for a lot of events
Maybe I'm just blind though
What conditions from your original message are you having issues with?
Yeah looks like there aren't any specific events you can listen to.
Ok, for future reference, I've discovered that I can listen for GenericGameEvent in Minecraft versions with sculk sensors and it seems to work 100% of the time
👍
These are the conditions I was checking for with PlayerInteractEvent aside from if it's a door or not, and this isn't even complete since it doesn't account for the offhand (I know it could be done better):
Block block = e.getClickedBlock();
if (block == null)
return;
if (block.getType().equals(Material.IRON_DOOR)
|| block.getType().equals(Material.IRON_TRAPDOOR))
return;
if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK))
return;
if (e.useInteractedBlock().equals(Event.Result.DENY))
return;
if (e.hasItem() && e.getPlayer().isSneaking())
return;
for objects it does
do you need the answer "right now" or is it ok to know it one tick later?
My workaround usually is to listen on MONITOR, ignore if cancelled, then schedule a task one tick later and then check if it's open now
if yes, it must have been opened by the event from 1 tick before
Ok
hello
There is an error in my code, and I've been sitting for an hour trying to figure out what the problem is
Use https://paste.helpch.at/ for errors, logs and configs. So we don't spam the discord.
Caused by: java.lang.NullPointerException
at org.bukkit.ChatColor.translateAlternateColorCodes(ChatColor.java:324) ~[patched_1.12.2.jar:git-Paper-1620]
the text is null
second))
There is 'messages.wrongCommand' in the config.
mine posting the config file aswell?
messages:
help:
- "&a=== Помощь по плагину SpigotTools ==="
- ""
- "&aКоманды:"
- "&6/spigottools tpsbar &f- Информация о сервере в боссбаре."
- "&6/spigottools serveranalytic <burdenplugins/info> &f- Информация о сервере."
- "&6/spigottools plugin <list/enable/disable> <plugin_name> &f- Управление плагинами."
- "&6/op <player_name> &f- Выдать права оператора."
- "&6/deop <player_name> &f- Снять права оператора."
- "&6/spigottools help &f- Показать эту справку."
- ""
- "&aИвенты:"
- "&6HighCommand &f- Выполняется команда указанная в конфиге если"
- "игрок коснётся высоты указаной в конфиге."
- "&6OpGuard &f- Защита от выдачи оператора игрокам."
- "&6Physics &f- Включение/Выключение физики"
- "&6LocalHost &f- Блокировка локальных подключений. 127.0.0.1"
- ""
- "&a=== Помощь по плагину SpigotTools ==="
no_permission: "&6Help &7| &fУ вас нет разрешения на использование этой команды."
wrongCommand: "&6SpigotTools &7| &cНекорректно написана команда! Напишите /st help чтобы увидеть помощь."
} else {
String text = config.getString("messages.wrongCommand");
sender.sendMessage(translateColorCodes(text));
return false;
}
return false;
}
only this works
just realized, this is the code for SpigotToolsCommand, the error says ru.blackdigo.spigottools.commands.PluginManagerCommand
so its an issue with PluginManagerCommand
mm
private String translateColorCodes(String input) {
return ChatColor.translateAlternateColorCodes('&', input);
}
line 139
code manager
oops
String pluginNameMissingMessage = translateColorCodes(config.getString("analytic.plugin.argsNone"));
)
I forgot to rename.
fixed)
is this will work for a victory dance?:
// Turn the sky to night.
world.setTime(18000);
// Play the Enderman teleporting sound.
playSound(player, "minecraft:entity.enderman.teleport", 1.0, 1.0);
// Duplicate the player multiple times.
for (var i = 0; i < 10; i++) {
var clone = player.clone();
clone.teleport(player.position);
}
// Spawn NPCs close to the player.
for (var i = 0; i < 10; i++) {
var npc = world.spawnEntity(NPC.class, player.position.add(0.5, 0.5, 0.5));
npc.setSprinting(true);
}
// Make the NPCs teleport randomly within the player's area.
for (var npc of world.getEntities()) {
if (npc instanceof NPC) {
var newPosition = player.position.add(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
npc.teleport(newPosition);
}
}
}```

i ripped that from an ai so i ask if it will work lol
I have so many questions
firstly
what the fuck
secondly
what the fuck
thirdly what language is that?
JS?
Why use KubeJS instead of writing directly in Java?
And finally, the indentation 💀
thats the smart ai bard not me im not a java dev
don't you just love it when people blindly copy the AI written code without really knowing what it does and if it's good or bad
iwas just want a victory dance to make someone understand me 🥲
I wonder what would happen if the AI told those people to jump outta the window
“Hello chatgpt please solve Fermat’s last theorem” easy
anyone know why my library on jitpack is saying "No access to repo" when its literally a public repo and it was successfully built on jitpack...
https://github.com/srnyx/java-utilities
https://jitpack.io/#xyz.srnyx/srnyx-java-utilities
because you don't have a repo named srnyx-java-utilities
:)
you can just copy and paste in the repo url btw
but i thought it'd still work cause of artifact id
:(
its based on repo url
ur readme also refers to the wrong repo
no
well yea cause i thought they'd work
xd
oh ok
just remember to change it back
btw note that your project artifact id is srynxJavaUtilities (defined in settings.gradle.kts)
I assume you want that to be srnyx-java-utilities
but to prevent duplicates, jitpack doesn't allow you to change the artifact id (although you can specify "sub" artifact ids)
no thats right
alr
i set the artifact id in the setup publishing thing
which honestly i should keep them the same but idc!
i think i fixed it
yep, all better!
👍
Does it have something to deal with ur implementationRelocate?
i dont think so as i tried just implementation too
ok barry
u can see that it just randomly broke after just adding/updating some dependencies; https://github.com/srnyx/annoying-api/commit/5832a610a5b457c0a6f938fb734ffb5521e324dd#diff-94ffd2c65a13014e00a66162041a62b546cd1d28e1a24b8165f2e0c415f7a357
Im on my phone rn so i cant take a proper look
implementationRelocate
good idea
🙃
thats a lot of changes in 1 commit tho
does it work in ur intellij?
if you gradle clean
nope, did gradle clean too
theres usually always something broken with the stupid sub-projects on intellij so i just assumed it'd work on jitpack
im uber brain
only cause i was replacing a bunch of stuff with new library to consolidate duplicate code across my projects
it wasnt working even before all the changes
except for updating the dependencies
i tested it only after updating dependencies so idk if it worked or not beforehand
just tested with reverted updating dependencies, still doesnt work
Are the classes it cant find from annoying api or java utilities
annoying api
aka the api subproject
ping if reply pls thx gn
Hello! There is an error in my code, it keeps saying that the player is not in the config list even though they are.
config:
guard:
operator_players:
- MagaVNavoze
- 09BlackDiGo09
console:
[INFO] op MagaVNavoze> Список операторов: [MagaVNavoze, 09BlackDiGo09]
[INFO] Guard Игрока MagaVNavoze нет в списке операторов. Нельзя выдать права оператора!
Guard Игрока MagaVNavoze нет в списке операторов. Нельзя выдать права оператора! = Guard | player MagaVNavoze is not in the list of operators. Cannot grant operator rights!
allowedPlayers.contains(sender.getName().toLowerCase())
also, use UUIDs to identify players
solves your other problem and makes you independent of name changes
Hello everyone, I am a web developer proficient in WordPress, front-end development, and coding. If anyone requires my assistance, please feel free to send me a direct message.
Hello everyone, I am a web developer proficient in WordPress, front-end development, and coding. If anyone requires my assistance, please feel free to send me a direct message.
hi there do you think that running a minecraft server in docker cause any performance related issues?
or anyone using already?
You double posted that message. Also use #1147713998612091010
Most hosts use docker. It shouldn't be the cause of any performance issues.
They do.
alr thanks that was useful
👍
i might be stupid but i have been trying to figure out why this isn't working. Here is my code and a screenshot of the problem: https://paste.helpch.at/sajofiyuje.java
The problem is that those items on the left are stacking with the items i am adding to the gui, on the left the itemstacks should be just 1, to fix that i tried adding a unique PersistentDataType to it so it doesn't match the other items being added but it seems that adding the unique thing to the items to the left adds it to all the items being inserted:
In my code, there is some error. I can't figure out what it is, nothing is outputting to the console or chat. There are absolutely no errors
code
core: Paper 1.12.2
The command is called like this:
case "serveranalytic":
if (args.length > 1) {
String analyticSubCommand = args[1].toLowerCase();
if (analyticSubCommand.equals("burdenplugins") || analyticSubCommand.equals("info")) {
if (args.length == 2) {
return pluginAnalyticCommand.onCommand(sender, cmd, label, new String[]{analyticSubCommand});
} else {
String text = config.getString("messages.wrongCommand");
sender.sendMessage(translateColorCodes(text));
}
onCommand:
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args)
I'm having issues with vite-plugin-html (Vite's equivalent of HtmlWebpackPlugin, https://github.com/vbenjs/vite-plugin-html), I'm passing my two pages but it only ever injects the JS into one of them, while the other HTML is left completely intact.
This is the code I'm running on build, mainly the injectCssOnHtmlFiles function, which just build the Vite plugin from the two htmls I'm passing in.
const test = fileName => {
return {
entry: `${envConfig.srcPath}/${fileName}/index.tsx`,
filename: `${fileName}.html`,
template: `views/${fileName}.html`,
};
};
function createConfiguredHtmlPlugin(fileNames: string[]): PluginOption[] {
const pages = fileNames.map(test);
console.log("fileNames", fileNames, `\npages`, pages);
return createHtmlPlugin({
minify: envConfig.isDevelopment,
pages: pages,
verbose: true,
});
}
function injectJsOnHtmlFiles(): PluginOption[] {
return createConfiguredHtmlPlugin(["options", "popup"]);
}
Only the last item in the the array HTML is considered by vite-plugin-html (and is correctly injected), while the first one is completely ignored. How can I debug this so I can find why the first page I create is always ignored by the plugin?
still having this issue :(
if it works occasionally its ready for production dw
I mean if it worked more then it didn't I would just add a check for list size lol
Yo folks, so I have a node program on my Pi. Currently starts via the command npm run start. How can I get this to work with pm2.
I've looked in package.json and it displays this:
"scripts": {
"start": "node src/accountHandler.js"
},```
Yet, when I point to that file for pm2 to run it just throws errors.
Any help would be awesome!
Still 😭 @dusky harness :)
I am currently developing a Minecraft PVP network that has basically private parties/duels. Essentially it is using Bungee cord, but I am very confused about the most optimal way of going about the internal structure of the server.
So basically you connect to the proxy, and that makes you join a lobby, you can switch to different lobbies from the lobby, or go into a private game/duel. This is when my question arises. I am not entirely sure what is the most optimal/best way to go about this because you have to give players a brand new fresh map to play on right.
-
Move them to alternate server, and generate a new temporary world for the map, and once match is complete it deletes.
-
Move them to a alternate server, everyone is on one world, no world generated. But some sort of change to the tab and chat so you can only see and talk to your duel. Essentially there are tons of maps laid down in this world spread apart, and when someone is in it, it is flagged as occupied so no player teleports there accidentally when there is already people. And then after the match is over a schematic is pasted/blocks altered are set back to normal, and that map is set as unoccupied
use Inventory#setItem instead of Inventory#addItem
second choice is definitely less resource intensive if you're handling a lot of duels, but depending on exactly how many you may need to do a mix of both
for example if you have like 30-50 duels going on at the same time at most, one server is probably enough and you can do as you described in 2)
if you expect significantly more you may want to have a way to distribute the duel participants over multiple instances of the duel servers
start with 1 as it seems easier/simpler to do, then if thats too resource extensive (or u just dont like it), u should be able to fairly easily switch to the more complicated 2 (easier as in not much harder than using 2 from the start)
but like ivan said, if u have a ton of duels, u may want to stratify all the duels into multiple worlds and/or servers (if there are tons)
example: 30 duels per world, 180 duels per server
Hello, I have a question why it won't let me place the GOLDEN_CHESPLATE config.yml: #FREEBARD
freebard-avaible:
material: GOLDEN_CHESPLATE
slot: 15
display_name: '&e&lFree Bard'
priority: 1
update: true
lore:
- '&aClick to claim this kit'
- '&7&m-------------------------------'
- '&6* &eCooldown&7: &f12 hours'
- '&6* &eStatus&7: &a&nAvailable'
- '&7&m-------------------------------'
- "&6Right-Click &eto preview the kit"
view_requirement:
requirements:
waiting:
type: string equals ignorecase
input: '%luckperms_inherited_expiry_time_waiting.cooldown.freebard%'
output: ''
left_click_commands:
- "[console] escobarkits give %player_name% diamond"
- '[message] &6[Kit] &aSuccessfully equipped Free Bard Kit!'
- '[console] lp user %player_name% permission settemp waiting.cooldown.freebard true 12h'
- '[sound] LEVEL_UP'
- '[close]'
right_click_commands:
- '[openguimenu] freebardpreview'
freebard-cooldown:
material: GOLDEN_CHESPLATE
slot: 15
display_name: '&e&lFree Bard'
priority: 2
update: true
lore:
- '&cYou have already claimed this kit!'
- '&7&m-------------------------------'
- '&6* &eCooldown&7: &f12 hours'
- '&6* &eStatus&7: &c&n%luckperms_inherited_expiry_time_waiting.cooldown.freebard%'
- '&7&m-------------------------------'
- "&6Right-Click &eto preview the kit"
left_click_commands:
- '[message] &6[Kit] &eYour still on &6Diamond Kit &ecooldown for another &c%luckperms_inherited_expiry_time_waiting.cooldown.freebard%&e.'
- '[sound] LAVA_POP'
right_click_commands:
- '[openguimenu] freebardpreview'
The GOLDEN CHESTPLATE should appear but nothing appears
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
• HelpChat Paste - How To Use
i always get this i have no clue how its called and how to get rid off it?
hit the insert key on your keyboard
sec iill fnd the key
ye
no prob
its legit the most useless feature they have in IntelliJ
it's not just an intellij feature
insert works in a lot of places
i do agree it's pretty useless tho
That always triggers me when I accidentally turn it on 💀
how can i make a listener run another class?
uhm
basically i have gui
when a player clicks on the item from that gui
its gonna open another gui
but i dont know how to make it open that other gui
just like you opened the current gui
that first gui is opened with a command
the code to open a gui/inventory is still the same
i dont really understand
@EventHandler
public void onLoreBookClick(InventoryClickEvent event) {
Player p = (Player) event.getWhoClicked();
if (event.getCurrentItem().getType() == Material.WRITABLE_BOOK){
}
}
}
i made the listener but i dont understand how to open the gui with it
but you managed to do that before?
as I said, the relevant code stays the same
im just gonna watch a tutorial then cause i dont understand
you already have everything you need
Is it possible to use an ExecutorService for SQLite?
yes?
How? I currently use this to make statements
public PreparedStatement prepareStatement(String query) {
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(query);
} catch(SQLException e) {
LOGGER.error("", e);
}
return ps;
}
And I want to use this executor ExecutorService EXECUTOR = Executors.newCachedThreadPool();
tldr is to use CompletableFutures
Iirc there’s some method like CompleteableFuture.runAsync(Runnable, Executor) so you can probably use that
But what would the runnable be? That's what I can't figure out lol
If you want to return something, you have to use supply (supplyAsync ?)
It’s a lot harder to abstract operations away like you’re doing when you have multiple threads involved
Ohhh yeah this would work I guess
CompletableFuture.runAsync(() -> {
try {
openConnection();
PreparedStatement statement = connection.prepareStatement(
"CREATE TABLE IF NOT EXISTS `" + OrbitalTesting.TABLE_NAME +
"` (`uuid` VARCHAR(36), `balance` DOUBLE)");
statement.execute();
statement.close();
LOGGER.info("SQLite file created");
} catch (SQLException e) {
LOGGER.error("Something went wrong while creating the SQLite file");
LOGGER.error("", e);
}
});
Wait forgot to add executor lol
yes although there are at least 2 red flags in that
1 being the global connection variable
the other being the lack of try-with-resources
Which? Not sure what you mean. This is just for initialization of the database btw
the one that you've written...?
openConnection();
connection.prepareStatement
connection is a global variable
Oh yeah didn't see that... Why should it not be a global variable though?
because just like statements or input/output streams they are resources that should be short-lived
plus global variables in general like that are just a bad practice
just create a new connection whenever you need one and close it when you're done (twr is also very handy for this)
Might be a dumb question but how else can I create it? Tried with final and that atomic thing but didnt work
once again you need to use CF
you cant return a pure value from an async context
thats not actually why you're getting this error but it's still not gonna work
return CF<Connection>, or just make the method blocking
sneaking in a monad tutorial hehe
connection pooling would like to have a word with you
iirc u dont need that for sqlite
just create/close 2000 connections per second
and even if you are pooling, that's usually abstracted away under the disguise of creating a new connection
it's better to not close the connection for sqlite (until shutdown ofc)
eventually yes but it isn't closed right away
huh
that's just how you tell hikari that it can reset all the funny timeouts
your mother
triggered sqlitecel owned by facts and logic
Wait so should I use pooling or create a new connection for every statement?
Also this looks like it works but is that what you meant?
Connection connection;
try {
connection = openConnection().get();
} catch (Exception e) {
LOGGER.error("", e);
return;
}
public CompletableFuture<Connection> openConnection() throws SQLException {
CompletableFuture<Connection> connection = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
try {
connection.complete(DriverManager.getConnection("jdbc:sqlite:" + orbitalTesting.databasePath));
LOGGER.info("Connection to database success!");
} catch(Exception e) {
LOGGER.error("", e);
}
}, EXECUTOR);
return connection;
}
well
firstly as emily said apparently it's ok to just keep the connection open if you're using sqlite
didnt know that
but ALSO
NOOOOOO do not use get()
you might as well not have the future if that's what you're doing
unless you're already in an async context, in which case it's probably ok
but also why is it throws SQLException if you're catching everything?
Oh, I'm not, but not sure how else to get the connection
no no no
thats the thing
you want to run all the code async
you (effectively) cant without escaping the future
which is good ^^
you just need to use all the CF methods like .thenRun to do all the rest of the work
thats what this means, once something is in a future you cant ever get it out
without blocking and making it effectively synchronous
Ah yeah, moved it into the CF
Not sure how this would be done? Sorry
well, for example ```java
openConnection().thenRun(connection -> {
connection.doSomething()
);
thenRun gives you a CompleteableFuture<Void> which you probably want to make initialize return
basically you're sort of chaining all the async operations into 1 big future, which you can then do error handling on or whatever
it's kinda unintuititve cuz it's totally antithetical to most of how imperative java works, but you can get the hang of it pretty easily
So thenRun would be inside runAsync?
Makes sense, but what should thenRun be used for then? I want to run this async I assume
but roughly converting this method, it'd look something like ```java
public CompletableFuture<Void> initialize() {
if (blah blah) {
return openConnection().thenRun(connection -> blah);
}
return CompletableFuture.completedFuture(null); // default case if there's nothing to do
the lambda passed to thenRun runs on the same thread that the future was completed in
Why would initialize return anything?
because CF's also wrap exceptions, and it can be handy to defer that error to the caller
alternatively you could just do the exception handling inside intialise
No parameters expected though
Ah I see
ah sorry thenAccept* not thenRun
made a little example
this is what it outputs
as you can see thenApply runs on the thread where the future was completed
so it's effectively already async
This is so confusing lol
any parts in particular? i can try explain more
I'm not sure what I'm doing wrong for initialization
Btw I really appreciate all the help :))
It works if I just remove the executor, but thats not what I want ig
I can use thenAcceptAsync and then provide the executor?
welcome to coding
@icy shadow Running into the same issue as before, when preparing statements, no idea how to change this so it can work
tbh
no offense or anything, but you should learn the basics of async programming in Java
Yes, I'm trying lol
well you're still using get lol
but look at the code, connection is never actually going to hold anything
you've never given it a value
I miiiight've fixed it?
public CompletableFuture<PreparedStatement> prepareStatement(String query) {
try {
openConnection().thenAcceptAsync(connection -> {
try {
PreparedStatement ignored = connection.prepareStatement(query);
} catch (Exception e) {
LOGGER.error("Error when preparing statement for query: " + query, e);
}
}, EXECUTOR);
} catch (Exception e) {
LOGGER.error("", e);
}
return null;
}
Yeah
return the result of thenAcceptAsync
also you probably dont need 2 try-catches
as i said earlier, CF's will automatically catch exceptions that get thrown so you only have to do the error handling in 1 place
How would this be done?
I tried with a local variable but not sure how it would work lol
Oh yeah..
Bruh
How can I parse it from void though?
Anyone knows how to connect a domain to minetrack server
probably not the right channel
sounds like a #general-plugins kinda question
or #minecraft
Ah yeah that works, is return null fine here? lol
public CompletableFuture<PreparedStatement> prepareStatement(String query) {
return openConnection().thenApplyAsync(connection -> {
try {
return connection.prepareStatement(query);
} catch (Exception e) {
LOGGER.error("Error when preparing statement for query: " + query, e);
return null;
}
}, EXECUTOR);
}
ehhh
maybe
if you're gonna do that I would mark the PreparedStatement as @eager saddleable
ffs
but i'd probably just rethrow the exception instead
that way it'll "bubble up" to where you call whenComplete or whatever
Ohhh that's smart, so just this?
sure
Removed exception from print
Should this also run in an async cf? Instead of using get
Ohhh I might've got it
fsr looks cursed
if you're using get you're doing something wrong
if you need the result of cfPs then use thenAccept
if you look at all the different type signatures it can make it a lot easier to see which function you need
fuck you
D:
CompletableFuture<Void> thenAccept(Consumer<? super T> action) consumer gives you the value with no result, so Void
Was about to ask where but yeah lol
Makes sense, thank you
<U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) thenApply is just normal function, analgous to Stream#map
I've got this from old code, what's the actual difference?
"SELECT * FROM " + OrbitalTesting.TABLE_NAME + " WHERE uuid = '" + uuid + "';"
"SELECT COUNT(*) FROM `" + OrbitalTesting.TABLE_NAME "` WHERE uuid = '" + uuid + "';"
Currently the first is used to check if the uuid is in the table but yeah
Seems a bit redundant to call to just check if uuid is there
What will the first one return if the uuid is not in any row then?
an empty result set
