Help coderanch get a
new server
by contributing to the fundraiser

Tim Holloway

Saloon Keeper
+ Follow
since Jun 25, 2001
Merit badge: grant badges
Biography
Long-time moderator for the Tomcat and JavaServer Faces forums. Designer and manager for the mousetech.com enterprise server farm, which runs VMs, a private cloud and a whole raft of Docker containers.
These days, doing a lot of IoT stuff with Arduinos and Raspberry Pi's.
For More
Jacksonville, Florida USA
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Tim Holloway

You have lots of choices.

You could simply use brute-force JDBC. Better yet, you can use Spring Data. For SQL databases, Spring Data has modules both for simple JDBC and for the JEE-standard Java Persistence Architecture (JPA). Spring Data will handle a lot of the tedious work that you'd have to do by hand otherwise.
1 hour ago
More likely, you're using different apps and they are using different display fonts.

Before everyone moved to UTF-8, Windows used something like CP-1256. Which seems to be in line with EE8MSWIN1250.

Of course, the other issue here is that JDBC-ODBC hasn't been a valid JDBC driver for a very, very long time. So I think you're working with an out-of-sate setup.
3 hours ago
Normally when I do a web search for Javadocs what comes back applies to some long-ago Java version.

So I tracked down the Java 21 docs specifically. And Blob is alive and well. Blob is an interface, not an instantiable class, though. I don't think that matters for your sample code.

So chances are that you haven't got Eclipse set up properly. Note that the JVM version setup for a project doesn't have to be the same as the one used by Eclipse itself, though.
3 hours ago
I suspect that you probably made the understandable beginner mistake of thinking that a webapp is a "program". That is, something you start, it runs and eventually it stops.

Webapps don't work that way. A JEE webapp is (strictly speaking) a collection of items stored in a specially-formatted JAR (which is itself a specially formatted ZIP). In actual practice, often when a webapp is deployed to a webapp server, the webapp is unzipped ("exploded"). For Tomcat, the WAR goes into the TOMCAT_HOME/webapps directory and the name of the WAR is used by default as the webapp context path, to distinguish that webapp from other webapps that migh also be deployed there. DON'T mistake a WAR structure for a file share. A WEB server is NOT a FILE server! URLs may look a lot like Unix filesystem paths, but they don't always act like filesystem paths and you cannot ever simply do open/close/read/write/delete operations on them from a web client,

WARs are more like Windows DLLs, then, than Windows executables.

To "run" a webapp, then, first you have to define one or more instances of the Servlet class or subclass (typically you subclass HttpServlet). I'll ignore JSPs, as they have their own mechanisms not important here.

Then you have to map a URL sub-path ("resource path") to that servlet class. Originally this was done by defining a logical servlet ID mapped to a path plus the same logical servlet mapped to a fully-qualified servler classname in the WEB-INF/web.xml file, but these days, there's an annotation that you can place in the source code for your servlet to make that task automatic. As I said, a URL path is NOT a "filesystem" path, so I can make a URL like "http://www.mysite.com:8080/mywebapp/foo" and it could use that mapping to reference the WAR resource /WEB-INF/classes/com.mysite.myapp.stuff.servlets.MyFoo.class".

So when a remote user sends Tomcat that URL, Tomcat will use the "/mywebapp" context path to local your WAR, then look at the web.xml data to resolve the resource path "/foo" to class com.mysite.myapp.stuff.servlets.MyFoo.class and Tomcat will look for its service() method and invoke it, passing the digested URL request data as well as providing response object to send it to. And no, webapps have no "main()" method. They don't run like apps, but are instead called from Tomcat.

Usually you don't subclass Servlet. The HttpServlet subclass overloads Servlet with a number of useful methods like doGet() and doPost(). The overloaded service() method looks at the incoming request to see if it's a GET, POST, DELETE, or whatever invokes the appropriate HttpServlet processing method.

Also be aware that when you type a URL in the navigation control of a web browser. that URL is always set as a GET request (valid request types are defined in an Internet standards document called an RFC). To make a POST, you have to submit an HTML form defined with a method type of "POST" or use an HTTL utility app such as "curl".

So, in short, you cannot define just any only processing method in a servlet and expect it to work. Tomcat won't know to even look for a "protected void processRequest(HttpServletRequest request, HttpServletResponse response)" and noy just because it's protected. You'd have to name that method "doGet()" to invoke it from a browser navigation, or doPost() to invoke is from an HTML FORM whose method="POST".
18 hours ago
It's important to realize that Java is not an "ASCII"-based language. Objects of type java.lang.String are Unicode. ASCII was a 7-bit code and did not support any characters with diaritics. Or more precisely, USASCII didn't, and that's what most of us are implying when we say "ASCII". When stored/transmitted in 8-bit form, the 8th bit was either used for parity checking or ignored, depending on hardware.

With the advent of the IBM PC. a variant of ASCII known as ASCIIZ was created and the 8th bit allowed for characters with diacritics.

But again, Java works with Unicode, and a Java character maps into a much larger bitspace. Big enough to define all sorts of characters, including Russion (Cyrillic), Arabic, Chinese, Japanese, even hieroglyphics and cuneiform. Also, alas, emojis.

So far, so good, but when storing extended character set strings in a database, then retrieving and displaying them, there are additional considerations.

The first is what code page the string or CLOB is defined under. That can affect the collating (sorting) order of strings. For example, for much of its lifespan, the default code pages for the MySQL database were an ISO8859 code page for Swedish. I have a recipe database app that got bitten by that, since my recipes aren't in Swedish!

But matching up code pages is only part of the battle. To display the proper characters, you also need a corresponding display font. If you're not using a font that maps to your code page, then you'll either get the wrong character displayed or get the "non-character" character (usually a box, "?" or "." or sometimes just blank or missing).

So everything needs to match up.

These days most systems, both Windows and Unix/Linux default to using UTF-8 as their standard code page. UTF-8 is a compactable form of Unicode.
19 hours ago

Tim Holloway wrote:Offhand, I can't think of a JEE-standard Validator



… Which only goes to show that senility is setting in hard for me. Because I believe that was the very option I recommended less than a month ago for a similar question.

Ron is correct. Although I think that the Spring Validator hooks into jakarta validator where applicable.
1 day ago
Offhand, I can't think of a JEE-standard Validator, About the closest approach would be the validator subsystem of JavaServer Faces, but that can actually tie into the Spring Validator.

I wouldn't get rid of Apache Commons Validator, unless it's not available for the context that you're developing in. While it's true that some Apache Commons modules have been phased out, if it works for your app, then keep it.

There's also the Spring Validator, since you're working with Spring. That was discussed recently here on the Ranch.
2 days ago
I'm suspicious of all the to-and-from string/byte array stuff here.

In the normal course of events, that would be OK, since Java knows exactly how many characters are in a String and a byte array. But internally, Java sometimes has shown signs of having come from the C world, where strings have a terminal null character that's the length determinator.

Because of all those conversions, I would not be surprised if somehow that ending null managed to leak into the byte array. Easy way to chec - just print the element at index 4 of the byte array (upcsat to int) and if it's '0', then there's your explanation. And if it's not, print each character in the byte array and let us see what the values are.

However, I'm pretty sure you can do what you need to do with fewer conversions by using more direct access methods with the encoder/decoder. And especially I'm leery of the "new String()". If for no other reason that character code page operations are done on the bytes it constructs from.
4 days ago
Yeah. I refreshed my memory on git sub-repositories and basically there are 3 variants on how to make one repo reference other repos, not how to make a repo that you could download fractionally like in svn.

As far as your own project breakdowns go, I have something similar but this is how I handle it:

I maintain a private Git server for myself and my customers. It runs gitea, which is a fork of gogs. The author of gogs unfortunately hasn't had time to keep the original project up to date, so a group of gogs fans spun off gitea.  You can find docker images of both systems the public Docker services, so if you're a fan of containers, you can get a gogs/gitea server up and running very quickly.

Like github, giteagogs allows multiple user accounts, so when I get a new client, I create an account for their stuff they create user login(s) to that account. Now in my case there are no common resources, o that's all they need. You can use Git's sub-repo features if  you find that manual connections are not sufficient for you.

My projects don't segregate into programming languages, so if I have a multi-lingual project such as an Android app, it's sufficient that I'd have a /src/main/java and /src/main/kotlin in my gradle build. If you're referring to human languages, that comes under I18N, and likewise there are mechanisms for that within a project.
You really shouldn't. Git works on an all-or-nothing basis.

I ran into something like this myself and looked at subprojects, but the whole thing was messy and confusing.

Fortunately these days, disk space is no longer so precious that I absolutely need to pull just part of a project.

If your subprojects are individual Maven or Gradle projects, the easiest way to manage them is to make each subproject an independent git project. That actually maps well to most IDEs, where the subproject is an IDE project.

You can, of course, simulate your SVN setup by naming projects "android-project1", "android-project2", "webapps-chess_app", and the like.

As a consolation, git allows you to quickly easily switch between branches on a project without making a separate branch directory. It has quite a bit of power. Plus the "git stash" feature can be useful if you're working on something and get interrupted.

Note that git only commits and pushes stuff that actually changes, also.
I think that the algorithm in question has an equal probability of generating the same value across its range. Internally, that's a float, but since integer truncation is consistent, the probability of getting a given integer value should be 1/10. The probability of getting the same value twice should be 1/100, if my maths are up to speed. So a histogram should be more or less flat.

Note I said more or less, as there's an old joke about the statistician who drowned in a lake that averaged only 2 inches deep. Your Mileage May Vary.
1 week ago
Stephan has moved into the transcendental. What's important is that you are "random enough". That is, if you cannot compute the next value even with all the information at your immediate disposal.

As an analogy, the UUID/GUID algorithm produces unique enough that to quote Kraig Brockenschmidt, the odds of two independent computations resulting in the same UUID are about the same as that a bunch of atoms will randomly rush together and produce a small walnut.

Likewise, NASA doesn't work with hundreds of digits of Pi, because after about 16 or so, the margin of error at the edge of the universe would be maybe 1cm.
1 week ago

John von Neumann wrote:
Anyone who considers arithmetical methods of generating random numbers is, of course, in a state of sin.


As quoted in Knuth's The Art of Computer Programming, Vol. 2 Seminumerical Algorithms Chapter 3.

Campbell can correct me, but I believe that the deterministic (pseudo) random number generator is the primary RNG for Java, as it is for most languages. It has value when running statistical simulations, for example.

True random numbers require non-computed inputs and are critical for things like secure network transports where you don't want outsiders to predict subsequent data parameters. I'm fairly certain that this option is now available in Java as well, but you'd have to dig farther to find it.
1 week ago
Welcome to the Ranch, Case!

Well, you've found one. The CodeRanch!

Often you'll find communities in your own hometown. Locally, we used to have a Java Users Group, although alas, not much heard lately. I believe there's supposed to be a registry of JUG's, though. I think there's supposed to be an active PHP group somewhere in this region, though I haven't checked lately. And so forth.

I won't mention some of the other programming forums I know of, because you asked more about social aspects, and, alas, some aren't very sociable. Useful, but not social.
1 week ago
The generation of (pseudo) random numbers is covered in Donald Knuth's seminal Art of Computer Programming. It supplies all of the necessary abstract information to create your own "random" number generator.

It's important to realise the difference between truly random numbers and pseudo-random numbers. In many cases, you want a statistical distribution, but you want to be able to re-create that exact sequence at will. Pseudo-random number generators are good for that, since for a given starting seed, you'll be able to predict exactly what the next "random" number in the sequence will be.

On the other hand, modern systems often require something more truly random. The Linux OS, for example, initialises its random number generator at boot time by collecting selected information from "noisy" sources, such as whatever happens to be flying around the network at that instant.

For even more randomness, scientists often add in noise from interstellar radio sources and/or radioactive elements. The use of cats in the latter is optional.

As for why generate in the range 0.0 <= x < 1.0? It's because you can easily scale and/or otherwise customise the output as you please without being subjected to the limits that programming a less general source would impose.
1 week ago