Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Objective Action
Jun 10, 2007



jit bull transpile posted:

Just FYI my crazy annotation stuff worked first try so thanks yall!

I'm glad your reflection solution got it sorted for you. Just for reading material there are two other options I've used over the years under similar circumstances. One is the JSR 269: Pluggable Annotation Processing API that was already discussed earlier. This lets you write, but not edit, new classes at compile time and has decent documentation from Oracle. If you ever want to go that route I very strongly recommend JavaPoet from Square as it makes it infinitely easier to write correct generated source.

The second, darker, way is to use the Element javax package (or the corresponding Eclipse compiler packages) and cast them to an AST representation and edit the node tree inline. This is a way to jam generated code into existing classes but relies on building on a Sun/Eclipse compiler implementation. Project Lombok and some AOP frameworks do this under the covers for instance.

Objective Action fucked around with this message at 03:22 on Nov 9, 2018

Adbot
ADBOT LOVES YOU

Objective Action
Jun 10, 2007



Regardless of the IDE you choose (I like Eclipse!) the one thing you should really internalize is that an IDE is not a text editor. Java lives and dies by a good IDE and mastering one can make all the difference.

The number of people that I've see open IntelliJ or the like and proceed to use it as a text editor that happens to have a build button is insane. Even people working in field professionally for years.

Automated refactoring: moves, extract interface, change scope of field, etc. Type hierarchies and the various semantic find/lookup tools. Automated imports, formatting, and organization. Intelligent templates and snippets.

Embrace the IDE, love the IDE, consume the IDE's flesh and make its power your own.

Objective Action
Jun 10, 2007



I will third Spring Boot as probably the most robust and easiest to get started with. If you want to play out on the edge you might try Quarkus as long as you don't want mind being stuck at Java 8.

Objective Action
Jun 10, 2007



I'll be the dissenter and say I like both Streams and the Flow API in 9+. I had to learn a lot of the basic concepts before that anyway working with Spark for data processing tasks at scale.

Couple of hard learned points:

1)
It is not appropriate to replace every loop or iterator with a stream. Streams and Flows (or Fluxes if you are on Java 8 and using Reactor) have overhead not associated with simple loops and if you are doing only very small computations you can actually spend more time setting up and tearing down things in the background than you do on the compute. This is why you will see people post about benchmarks a lot as well. Think of Streams as basically a ThreadPool or Executor implementation with a built in message passing subsystem and some pretty smart compute graph optimization schemes hiding in the background adjudicating exactly how much actually needs to get done to satisfy a request. The one upshot of using a stream where it might not gain you an immediate benefit is that, as the underlying implementations get better, old code might get a little bit faster the next time it gets recompiled the same way you typically get speed benefits using matrix math libraries when someone figures out an optimization.

Bad:
code:
stream.map(i -> new X(i.field)).collect(...)
Better:
code:
stream.map(bunch of matrix operations).flatMap(network operation on the result).filter(...).collect(...)
It is also silly to replace simple array indexed loops with range, or worse, zip streams in almost every case; Its more complicated for usually no reason at all.

2) By the same token it is not appropriate to go hog wild replacing objects, or even methods, with lambdas all willy-nilly in every case. Its pretty drat easy to slip back into imperative programming without realizing you are doing it.

Bad:
code:
class Foo() {
	int x = stream.map(v -> {
		Five hundred lines of code here
	}).zipWith(val1...{
		A thousand more lines of code
	});
}
Better:
code:
ResultType validatedFoo = stream.map(v -> getFooFromBar(v)).filter(ValidatedFoo::isValid)...
3)
Streams and flows are lazy by default and try to be immutable where they can get away with it too. You need to call a terminal operation to trigger anything actually being done. A side effect of the implementation is more stack traces and log messages can get swallowed in closures than you might expect going in. The immutable part can creep up on you in some interesting and sometimes subtle places like the differences behind the scenes for .collect and .reduce.

4)
Streams and flows only really shine when your code is a) parallelizable and b) results in an asynchronous callback/event notification or may actually never terminate for the life of the program. This is great because you can make your code run in parallel by just popping in 'existingStream.parallel().{rest of the ops}' but the caveat is that if you, today, threw that same code in a threadpool and it misbehaved you aren't magically going to be in any less trouble in a stream. You can get a fair amount done with traditional control flows that you might have done with an executor in 7 but some subtle architectural difficulties can pop up if you try to cram code that might not initially look tightly coupled into a flow and suddenly start hitting halting and communication problems you didn't know you had.

I will say that the one other place they are quite nice as a default option is the I/O stream enhancements, particularly for files, they made in 8 which have basically replaced 99% of my use cases for those modules.

Objective Action fucked around with this message at 04:42 on May 9, 2019

Objective Action
Jun 10, 2007



PierreTheMime posted:

Very cool! I’ll have to test it out because the current implementation is causing me a huge headache. The real kicker is it’s actually the Docker container in an ephemeral EC2 that’s going OOM so tracking down the real cause is both new/annoying.

I might just be dumb but when you say stream do you mean java.util.stream.Stream or are we talking the java.io.In/OutputStream packages, or both? I got very confused and was going to start talking about how to work with ForkJoinPool limits and recommend Flows and/or a reactive stream library like Reactor but then I went back through your posts and only see IO packages actually being used.

If the problem is memory overhead on the IO packages I think Labmda will cap at ~3000mb per function unless you request a limit increase. You can see in CloudWatch what you are actually using per invocation by looking for "REPORT:" lines; should get one per invocation.

Couple things about IO streams that might bite you depending on the rest of your code. Make sure you have a finally block or try-with-resources (if your stream is AutoClosable) for every stream you have. Its very easy to accidentally leave a handle open and end up with a slow leak you wouldn't notice until you really start cooking. The other thing is depending on which implementations you are using they might have different underlying assumptions about when and how they actually flush their buffers so you might well have more stuff in memory than you expect depending on that.

Its not quite the same use case as what you have but one thing I've found useful when I was using Lambda for computing some stuff it wasn't really designed for is wrapping a callback function to a tiny EC instance pilot light style state cache. Then I would just periodically checkpoint to the state cache and read the checkpoints back out on starting up the function. Crude but worked a treat to avoid re-computing results I already had.

Objective Action
Jun 10, 2007



The bi-directional thing might be bad design ER wise but the actual error is unrelated. It's saying "no Session" because by the time you call the add() method (which hashes the Category) you aren't in a transaction anymore. Specifically when you hash the category it tries to fetch the recipes collection which is still lazy-loaded because you only marked one end of the collection eager.

It's been a minute but I believe the Spring *Runner methods don't have the right type annotations to be set up for transactions correctly in run(); mostly because Spring does that by wrapping the classes in a AOP proxy on the fly. Move the JPA code to a service or component annotated as @Transactional and inject it as a dependency into the Runner so Spring can wrap it in a proxy. Then either fetch it explicitly in the transaction method before you return it (preferred) or set it to Eager. You might also want to explicitly detach the objects depending on how/if you want to save any modifications but that is a problem for another time.

p.s. I like Spring a lot but they set Open In View enabled by default in their JPA implementation to try and protect people from some classes of mistakes. This is incredibly slow in quite common use cases and can cause subtle errors in others. I pretty strongly recommend settings "spring.jpa.open-in-view=false" in your application properties file of choice. You might get some more lazy exceptions with it off but you want to fix those anyway and the more subtle problems are not worth the headache.

Objective Action fucked around with this message at 04:51 on Sep 7, 2019

Objective Action
Jun 10, 2007



I can't help with Payara specifically (we were a JBoss shop) but if you can run it with flight recorder the first thing I would do is turn that on and dump out some recordings of the server under some different loads. If its really trash under such light load any particularly egregious problems should bubble out fast. If you don't have licenses for that but you can run it on an 11+ OpenJDK its available there as well free.

The only real problem is if you have a piece of software so incredibly uniformly trash everything kind of cancels out and all the graphs are just up and to the right. :haw:

Objective Action
Jun 10, 2007



Hmm, I haven't had this problem in the last few years but earlier versions of Lucene were pretty bad about about corrupting indexes on me when we were hitting an OOM reaping cycle. Some wing-nut had set a larger max heap size than we actually physically had available on the node and every once in a while we would actually dump enough load on a shard to hit the cap. You can get those on power outages or other unexpected dropouts as well.

You might see if the errors are IOExceptions about specific files to clue you in on that if that is the case. If you are lucky they will all be 0 byte files and you can clean them up directly. Its a bit trickier if they are partial writes, you would have to go to the docs for your version of Lucene on that one but hold off till you know if that is even the problem probably.

Best of luck!

Objective Action
Jun 10, 2007



Twerk from Home posted:

I inherited a project with a production Spark cluster that has... a grand total of 45GB of memory across the entire cluster, driver + workers. Even this seems to be oversized.

What are the advantages of Spark at very small scale? My layman's assumption is that Spark is only a tool you reach for when a single dataset in memory outgrows what commodity instances can provide, but I'm deep diving on spark docs and exercises to make sure I'm not missing something.

At that scale there are still a handful of reasons you might use it although its definitely not the primary use.

Specifically it might still be useful for:
* A very heavily I/O bound problem that doesn't need much RAM, read->reduce or lots of writes for instance?
* It does also have some decent APIs for streaming use cases
* There are some nice Spark SQL adapters to get DataFrame in/out of various data sinks (doesn't beat a dedicated ETL system but can do)
* Managed check-point and restarting for long running jobs that you want to be resilient

So sure, not the primary use case and there are plenty of more specialized tools that can do each of those things more easily/better but I could see it even on such a small cluster.

Objective Action
Jun 10, 2007



i vomit kittens posted:

code:
        postUrl = "https://image.groupme.com/pictures"
        files = {"file": open(filename, "rb")}
        payload = {"access_token": "----------------------"}
        r = requests.post(postUrl, files=files, params=payload)

Its a little bit difficult to tell without testing it myself but looking at GroupMe's (poo poo) documentation for that endpoint just says it wants a binary payload in the body where I know requests.post(...file=blah...) usually does a multi-part form upload encoding.

Java has a million excellent web client libraries but given you are already in Spring Boot land the two quickest options are probably RestTemplate and the WebFlux WebClient. I prefer the latter's API myself but here are some examples that I believe should mimic what you have. (Note this is not the cleanest and least boiler-platy way to do this but is a complete example without any dependency injection or anything).

code:

byte[] imageBytes = //Volguus' example
String accessToken = //token

//RestTemplate style
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("files", imageBytes);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
headers.set("X-Access-Token", accessToken);
     
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
 
String serverUrl = "https://image.groupme.com/pictures";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(serverUrl, requestEntity, String.class, accessToken);

//WebClient style
WebClient client = WebClient.builder()
        .baseUrl("https://image.groupme.com/")
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG)
	.defaultHeader("X-Access-Token", accessToken)
        .build();

client.post()
	  .uri("/pictures")
          .bodyValue(imageBytes)
          .retrieve()
//You can also just do String.class if you don't want to marshal an object or use exchange instead of retrieve to get things like response codes and have finer control over results
          .bodyToMono(GroupMeImageUploadResponse.class)
	  .subscribe(response -> //Do things with response);

Note these are from memory and might not even compile without some tweaking but should be pretty close I think.

Objective Action
Jun 10, 2007



Splinter posted:

True that whenever a DB migration is run the import service and webapp will both need to be updated to reflect the new schema at the same time. But outside of schema changes, I'd like to be able to make updates to the import service without taking the webapp down (and vice versa). Maybe I'm thinking about this the wrong way.

In terms of shared data access, the the import service will need to fetch from the DB in similar ways as the webapp in some cases. I'm not currently expecting to need to add CUD functionality to the webapp, but were that to happen, it seems like shared DAOs would make this easier. Maybe add a service layer between the DAO and each app that exposes different DAO functionality to each app? At the bare minimum it seems like it would be good to have the DB mapped Entity classes defined in a single location, as I expect there would be a lot of duplication there otherwise.

Knowing nothing else I would probably go with something like (as you already laid out):
code:
Database Access (Flyway + DAO/Hibernate)
      ^
      |
      |
|----------------|
Ingest           Webapp
But that doesn't necessarily account for if/when your webapp starts wanting to touch tables the ingest doesn't know about and vice-versa so might need to split the access up later into a few DAO packages. That being said if you haven't already look at Apache NiFi for your ingest needs. I've used it for small things and multiple PB jobs and it works like a champ. Its easy to set up and has a million pre-built ETL tools and fairly decent docs on how to write your own new ones.

Objective Action
Jun 10, 2007



I think the problem in my mind is in trying to disambiguate what we are talking about when we talk web apps. You mention front end but then all the projects listed are geared towards service applications serving REST endpoints. To be fair I don't think that's your fault at all since searching for Java + Web anything is going to flood out the results with those these days. Of the ones listed I would say stick with Boot and only open the Spring can of worms one piece at a time when you want to add a new feature they already have into your code. Don't try to eat the whale whole.

I'm using WebFlux and its quite robust but its also designed to be entirely non-blocking, and highly concurrent, so many of the follow-on decisions on how the API works can occasionally make debugging it and reasoning about problems a little more difficult than normal. If you are comfortable using parallel map/reduce semantics its pretty good though.

Now as for web applications actually written in Java that landscape is pretty narrow. Most of the old projects in that space are really old and decrepit. To my knowledge the three biggest real boy projects still kicking around, maintained, documented, and with active user communities are Vaadin, Play, and Struts. All three of these are totally usable but keep in mind the newest of these was first released in 2007 so even though they all are still actively releasing the API isn't going to be whatever the new hotness is today. Also I have no idea how robust their Kotlin support is.

Mostly these days when I want a web app I write it in Typescript and then deploy it with Boot or JBoss WildFly/Thorntail (which is basically JHipster but by hand).

Objective Action
Jun 10, 2007



Love Stole the Day posted:

Spring Maven/Gradle question:

When we add a new dependency to a project, where can we see what new editable configurations are exposed to us in the project's application properties file?

For example, adding Spring Boot Data MongoDb as a dependency exposes spring.data.mongodb with a bunch of child things... but where can we see the reference for all of those things?

At the moment, my only option seems to be to just look up a tutorial example of someone else using it and then following their example.

There are a bunch of ways to do this at different levels. Most jars are supposed to include a configuration metadata file in src/main/resources but that can be hit or miss. If you really need to get at that from Maven/Gradle you can unpack resources and get at least some info that way.

A simpler way to debug quickly is just plunk in a class to log out the properties ala this snippet.

My favorite way though is to use Spring Actuator to turn on the /env endpoint dynamically since I can do that and other stuff on the test servers dynamically over JMX. It also gets you some nice log level switching features (please dev only!) and some health and metrics poking if you really need it and don't already have something like Flight Recorder or Grafana/Prometheus set up.

Objective Action
Jun 10, 2007



my bony fealty posted:

word has come down from high at work that our dev team will probably start having to do some Java work soonish. I have zero Java experience, can anyone recommend resources/courses for getting started? the link in the second post here is a bit old so not sure if there's something more recent to look for. there's a few of those monolithic 70 hour courses on Udemy of course.

for context I am a dirty front-end developer who writes mostly JavaScript and has a good amount of PHP experience. thanks!

Effective Java is your best bet for getting the language basics down. The thing to understand about Java is it is very old and depending on which version of Java you can code to you will have wildly nicer and more modern options for things like threads, file interactions, etc. You can do all that basically back to Java 1 but it gets more annoying the further back you go. If something feels fiddly as poo poo there is a very good chance there is a better and more modern way to do it and whatever documentation/stackoverflow you were looking at is out of date.

Some recommendations I can really make about Java coming from other languages is it has some of the finest tooling chains of any language in existence. I know people who insist on writing Java in Vim/Emacs/Notepad; those people are loving lunatics and you should not listen to them.

1) Find an IDE you like and learn the IDE's functions. I see a lot of people using the IDE like a really heavyweight text editor which is missing the point badly.
2) Learn the Java syntax, notice this is #2!
3) Start learning about the debugging and profiling tools. Flight Recorder and VisualVM are both free and get you 90% of some of the best tools around for that poo poo.

Objective Action fucked around with this message at 03:40 on Apr 16, 2020

Objective Action
Jun 10, 2007



As long as you don't want to store a tremendous amount of state a Session EJB in Java EE terms would possibly do what you need. This is old documentation for Weblogic (gag!) but the diagrams are still relevant: https://docs.oracle.com/cd/E11035_01/wls100/ejb/session.html. Comes with some rudimentary support for various kinds of clustering and redundancy if you scrounge around the various docs.

Generally anything compliant with Java EE 6 (er, Jakarta now I guess) which is fairly old and well supported would do it. Tomcat, JBoss (Wildfly, Thorntail, whateverthefuck-they-renamed-it-this-week). If you already are running in a web container it would be fairly easy to drop in and test and it would remain implementation independent. Depending on the size and scope of your need though something like Redis or plain old Postgres wouldn't be all that much more work these days honestly.

Objective Action
Jun 10, 2007



Guildenstern Mother posted:

Thanks, I was totally unaware you could just tack them together like that. Can you explain a bit more about when I should and shouldn't autowire repositories? Its a thing our lecturers have always had us make a point of doing, but if its bad practice I don't want to keep doing it unnecessarily.

This is going to sound really mean but I promise I am trying in good faith to help you from a place of bitter and hard won experience.

You have some fundamental misunderstandings about how this all works.

The good news is this is not uncommon at all, especially with frameworks. It sounds like your instructor has started you guys out with Spring Boot to try and make it easy to do really complicated stuff under the hood (like have a REST service) without needing to think about the guts too hard at the start. This is good and fine but if you are fundamentally confused about how the basics of the language and the framework work you are going to be miserable the second something doesn't work correctly or you want to do something outside the pale for the framework.

Fundamentally the current problem you have makes more sense if you step back and think of this as just a class and Spring as another person. What you have is a class you can build in two ways. It can either be a class to do things with a BBRepository (B) or a class to do things with a UserRepository (U) (there are other problems with that but lets ignore that for now). What you have done by making them both marked @Autowired is asked Spring "Can you make a class that does things with an A, then make that same thing at the same time with a B?" when you meant to ask "Can you make a class that has an A and a B". The first sentence makes no sense at all and the second one makes perfect sense.

What Spring was trying to report there is a common problem with all frameworks, it doesn't have context to give you a good human readable error that explains that exactly because from its perspective that kind of error can show up in all sorts of situations. This is a good example of why having some inkling of how the magic works is so important to making solving problems much less frustrating.

What Spring's injection library is telling you there is "Hey wait, you gave me two ways to make this class. I can do that but since you can only call one constructor in Java you need to tell me which one gets priority". In this case you have a class that has no default constructor, neither of the @Autowired ones have any other context to break a tie, and so Spring either has to guess (bad!) or give you an error (better!). You could absolutely have a class like this that works as a BBRepository frobulator when you launch the application as a client and a UserRepository munger when you are running as a server. To do that you would need some way to know and tell Spring which to use. There are approximately a million ways but just think of it as a theoretical annotation you add in addition to @Autowired, lets call it @Conditional, so you make one as @Conditional(class=Foo.class) and the other @Conditional(class=Bar.class). Then Spring would look at what classes are in the classpath and if it sees one but not the other it knows how to break the tie.

This is a bad idea and bad practice; but you could!

As for your actual question you don't have to annotate the constructor @Autowired in modern Spring but I would recommend doing so anyway (or use the more generic @Inject) just to mentally keep it straight as to what is happening. There are a lot of people that will crow about how to use or not use dependency injection but there are pros and cons to everything. Generally you want to be taking advantage of your dependency injection wherever you can because it encourages breaking things up and making them more modular. My personal preference is to use constructor injection only and never use setter or field based annotations. This lets you throw away, change, or sidestep the DI setup you have and still make your classes by hand with fewer headaches. This also tends to make it easier to deal with testing those classes in unit tests.

The best thing you can do is step back and read some documentation on how Spring Boot is doing what its doing at a rough high level. Spring is a giant bundle of a lot of other styles of programming, libraries, and sub-frameworks so to narrow down the reading you probably want to just look at the documentation for dependency injection in general and Spring's implementation specifically. This will be boring. It is absolutely worth it.

Objective Action fucked around with this message at 14:16 on Sep 9, 2020

Objective Action
Jun 10, 2007



It might not be quite as hands on as what you are looking for but I will always take time to shill for Joshua Bloch's Effective Java as a good overall handbook.

From there what I would do is go to GitHub's trending page and sort by Java and find 2-3 projects that are interesting and spend some time building them in your IDE of choice and poking around. It might not be the cleanest or most well put together code but its likely to be way more informative about real world conditions you are likely to see in the wild. Make sure its a project that does something you are personally interested in! If you pick the most popular thing you will just burn out before you learn anything useful looking at the code.

Objective Action
Jun 10, 2007



gently caress var forever. Take that poo poo back to Scala nerds!

Objective Action
Jun 10, 2007



RandomBlue posted:

Strongly typed local variable type inference is actually good most of the time unless you like repeating yourself on the same line:

OmgType varName = new OmgType();

As someone who has spent literal weeks of my life digging through other peoples code to figure out which undocumented type was being injected and which of the seven interfaces happened to be used at the moment the library was being called: we are going to have to agree to disagree on this one.

Here is a nice Scala example that took fifteen minutes of my life yesterday:
code:
val filterFuncs = filters.map(filter => createFilterFunction(filter))
Strongly-typed right? So just ask the compiler or IDE!

Nope, that unrolls into six layers of three different interfaces and four traits. Time to slap a logpoint or debugger onto your code like some kind of goddamn caveman.

Objective Action
Jun 10, 2007



I'm not trying to dogpile on you or anyone specifically but this whole concept of "less to type" being important to people still baffles me a little. I spend maybe 10% of my time typing in code and 90% reading code, thinking about what I want to do, and how I want to do it.

Being easy to write is less important to me than being easy to read and digest what the hell a piece of code is doing. I have this argument with people constantly about things like APL where every bit of code ever produced for that is effectively write-once.

Objective Action
Jun 10, 2007



The thing to keep in mind about the module system is that it was severely mis-marketed in being sold as some kind of OSGi style module system. In reality the original use-case, and the only real need for it as-implemented, is to break up the JDK into modules to make future work and distribution on that easier.

For me, as someone who has specific regulatory and security requirements, being able to use jlink/jpackage to build a JRE with only the specific modules I need to make my application deployment run is a godsend. I don't have to hack up my own copies of the JDK/JRE source in a forked repo anymore just to cut out specific modules which saves me a huge maintenance burden, cuts down on bugs, and lets be drop features that have large attack surfaces that we aren't even using.

That being said I do agree that the implementation causing compatibility problems without offering better developer level features, something like real OSGi style modules, is a bummer. Fortunately I don't think we are looking at a Python level split as the compatibility problems turn out to be fairly small once you get down in the weeds upgrading.

Objective Action
Jun 10, 2007



I know it feels weird coming from C/C++ land to have to work with inline compilers and give up some direct memory management but they really have gotten very good over the last decade or two.

We currently run a system that transitioned from FORTRAN to Java for running computations on ~1M*1M matrices and after months of sweating performance worries about that we found out that we were within ~5-10% of the FORTRAN performance and we got more bang for our buck working on better node scheduling algorithms than trying to super-optimize what the JIT/GC was doing beyond the basics.

Objective Action
Jun 10, 2007



Others have already covered my recommendations (Clean Code and Effective Java).

Once you have those under your belt one other thing I highly recommend is get a free copy of SonarQube, turn all the rules on, and scan every piece of code you write. There are plugins for every major IDE and standalone apps if you can't use an IDE for some reason.

~70% of the results will be opinionated bullshit but you will catch poo poo you never thought of and looking at the opinions and being forced to think about why you don't agree with that and are turning off the rule is very valuable imo. It won't teach you concepts to get good clean code the way the books will and it won't catch more elaborate logical errors but it absolutely will help you practice and can be useful to find spots where you have a knowledge gap.

Its some of the best code analysis tools around packaged into a super convenient frontend and you should absolutely take advantage of it.

Objective Action
Jun 10, 2007



I'm actually working on a project right now that uses JavaFX's WebView as an Electron alternative where the widgets are all Angular/HTML5 and bind back to Java processing code via the JSObject bindings. But then again I am a crazy person.

If you are interested in GWT there is a community maintained fork on GitHub but there is also a fork that still has free usage options and some more modern features in Vaadin that is maintained and used by a social network company in Germany.

Objective Action
Jun 10, 2007



For that project they already had a large existing GUI codebase in Java. 1M+ lines with copyrights 1987-2021. By taking the JavaFX path we could use the Swing panel interop to start transitioning pieces and parts in the existing deployment without needing to do a greenfield re-build.

That project also has some specific deployment requirements around packaging, runtimes, and target OSes that made it much easier to stay entirely in the Java ecosystem so we could keep the same footprint.

Overall it was actually quite a bit less painful than I feared. The only notable problem vs. electron, other than missing all the nice integration and tooling, is that the Webkit engine JavaFX uses doesn't compile with WebGL support. If we ever need to use that I will either have to compile and build the bridges myself or, more likely, switch to the Java Chromium Embedded Framework.

Objective Action
Jun 10, 2007



If you are already using Spring it might be worthwhile to look at something like the GraphQL integration to see another way to go about handling that problem as well. Even if you decide not to use it just looking at the way they built the API might give you some ideas.

Objective Action
Jun 10, 2007



Paul MaudDib posted:

two questions, the second may obsolete the first but I've been wondering about #1 anyway so an answer would be great if possible:

1. We have a List<Object[ ]>. What I want is a list of stream.map(row -> row[0]) - each element in the list is an array, I want the first element from the array. Can't quite figure the syntax on that.

2. In hibernate, when you are doing a "SELECT a, b FROM ..." what you get is an array by default. I can't remember, is there a nicer syntax for telling a query that it's going to return a Tuple<MyEntity, String> or something like that?

1. For a List<Object[]> your proposed syntax should be correct. List<> foo; foo.stream().map(arr -> arr[0]) should go from List<Object[]> to Stream<Object>?

2. If the object you want has a no argument public constructor and is a bean that matches all the field names you can just make the return type of the query the object and Hibernate will map it:
Thing t = query.execute("select blah1, blah2 from OtherThing").

Otherwise you can call a constructor from HQL directly:
Thing t = query.execute("select new Thing(o.blah1, o.blah2) from OtherThing o").

Objective Action
Jun 10, 2007



Specification is ambiguous but I had inferred that the problem was that a Car Lot is a specification of an ItemInventory<Item> and a Car is an Item, so therefore CarLot | ItemInventory<Car> and Car | Item or equivalent.

Makes more sense that way at least.

edit:

Also please stop returning and specifying concrete return types when you don't use any of the concrete methods. Return List<> and not ArrayList<>!

Objective Action fucked around with this message at 00:49 on Dec 1, 2021

Objective Action
Jun 10, 2007



HamAdams posted:

loving around with Spring in some side projects to get a little more familiar and something I haven't been able to settle on is whether to use constructor params or the @Autowired annotation. Is there any reason to use one versus the other? I'm guessing there's probably some gotchas that I just don't know about yet.

I'd recommend using @Autowired on the constructor parameters rather than the fields directly. Makes it easier to build specific instances manually, makes the signature explicit, makes tests easier, etc. Also more options later if you want to change out the DI for another implementation like Dagger or Micronaut that pre-compiles.

Just my opinion though.

Objective Action fucked around with this message at 17:13 on Jul 4, 2022

Objective Action
Jun 10, 2007



hooah posted:

Does anyone have any recommendations for generating an OpenAPI 2 / Swagger document from annotations using Spring Boot 2.6.x? We're currently stuck using OpenAPI 2 at work, and Springfox doesn't work with Spring Boot above 2.5.x.

I use https://springdoc.org/ but that's OpenAPI 3. To my knowledge the only option for 2.0 (that was anywhere near usable) was Springfox. If it absolutely has to be 2.0 I think your only option might be to check for forks or fork Springfox yourself?

Objective Action
Jun 10, 2007



The trick with embedded databases is in the long run they all have that problem. I've had plenty of SQLite databases eat themselves over the years too. I use H2 a lot and it has lots of really nice features a lot of the other embedded ones don't, like multithreaded access modes, BLOB compression options, Postgres mode, optional embedded web-gui, ability to support multiple clients and transport protocols, etc.

That being said it might be using a sledgehammer to swat a fly depending on what you are doing. SQLite can be fine if you just need table storage without sweating the bells and whistles or if you just want a more cross-language supported way to store data. For instance I do have one application that has both a C/C++ app and a Java app so we standardized on SQLite instead of trying to support an interface or service layer abstraction. Not optimal but given the scope of that app it made the most fiscal sense.

No matter which database you embed though you will eventually want to have a set of startup routines to attempt auto recovery and run any maintenance functions the DB in question provides to clean up transaction files/etc.

The only one I wouldn't really recommend is probably Derby, its been flakier than either H2 or SQLite for me and the recovery options always seemed worse. Just a personal opinion though.

Objective Action
Jun 10, 2007



Ornedan posted:

Are these some optimisation flags Eclipse enables by default that could cause the difference?

Eclipse has its own compiler actually. They do that because they can do incremental compilation, some limited hot-swapping during debug, and it allows running code that has partial errors (sometimes).

That being said profiling Java code is a surprisingly delicate problem because, as you have already seen, the JVM under the covers is doing all sorts of just in time compilation caching and optimizations.

Generally I would recommend that you use something like the Java Microbenchmarking Harness and also that you put the code into a loop, let it execute a few times, and then run it for a few thousand iterations and aggregate the results. That will let the JVM have time to warm up and do its runtime optimizations so your numbers are more likely to be honest to real world performance.

If you are feeling really bold you could also look at using some of the new ahead of time compilation tools in JDK 17+ or GraalVM to pre-compile down to native code. This should eliminate the JIT warmup speeds if you have stuff that runs only rarely and only one or two times per lifetime of the application.

Objective Action fucked around with this message at 16:14 on Jul 9, 2023

Adbot
ADBOT LOVES YOU

Objective Action
Jun 10, 2007



Nice work! Always nice to see people doing fun stuff and reporting on it in the thread.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply