|
OK, so there isn't something to specifically tell it, like socket.ImDone(), but in the context they speak to each other. In that case, I'm using something like that in main project. The example in main thread was something simple, to only address java.net.ConnectException: Connection timed out problem, which was in fact caused by antivirus firewall.
|
|
|
|
|
2.1 Define what is meant by a programming paradigm and explain the characteristics of different programming paradigms (Procedural, Object-Oriented, and Event-Driven) (Report).
2.2 Develop Java code examples for a certain scenario of your choice that implements the features and the characteristics of the different programming paradigms (Procedural, Object-Oriented, and Event-Driven). You should utilize the concepts of Encapsulation, Composition, Inheritance, and Polymorphism in your Object-Oriented code. (Code).
2.3 Compare and contrast the features and characteristic of each paradigm that you have used in developing your code in (2.2) (Screenshots of Code) (Report).
2.4 Critically evaluate the code examples that you have developed in (2.2) in terms of code structure and characteristics for each paradigm (Screenshots of Code) (Report).
|
|
|
|
|
Member 15912696 wrote:
full answer with code pls
Err...no thank you.
|
|
|
|
|
No. Nobody is here to do your work, or more importantly, your homework, for you. You learn nothing from that.
Frankly, I find people who ask others to do their work for them lazy and insulting to others and themselves.
|
|
|
|
|
How did lazy make it in here, rap over knuckles a few weeks back pops to mind.
|
|
|
|
|
|
Sounds like "term" stuff ... should cost you about $10,000 for someone else to do it.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
In order to use JNI, you have to add inside Environment Variables (User or System) the path to were jvm.dll is located. You have a few ways to do that, but it is possible. But, is there a way to not have to add the path inside Environment Variables and instead when you call the function to create a VM from C++ to tell it where it is located via JavaVMInitArgs , or maybe JavaVMOption , or in any other way, but like I said without having to add the path in Environment Variables ?
|
|
|
|
|
Yes, this is the way I do it, but you can modify it any way you like to provide the path to the library:
#include <Windows.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <filesystem> // requires -std:c++17
#include "jni.h"
HMODULE LoadDll(
const char* jrePath
)
{
const char* pszjvmname = "bin\\server\\jvm.dll"; HMODULE hJVMDLL = 0;
std::filesystem::path jvmpath(jrePath);
jvmpath /= pszjvmname;
if (!std::filesystem::exists(jvmpath))
{
std::cerr << "JVM library " << jvmpath << " not found." << std::endl;
}
hJVMDLL = LoadLibraryW(reinterpret_cast<PCWSTR>(jvmpath.c_str()));
if (hJVMDLL != NULL)
{
std::clog << "jvm.dll loaded from: " << jvmpath << std::endl;
}
return hJVMDLL; }
JNIEnv* AttachJVM(
const char* jrePath,
JavaVM* jvm,
std::string strcwd
)
{
HMODULE hJVMDLL = LoadDll(jrePath);
if (hJVMDLL == 0)
{
return nullptr;
}
typedef jint(JNICALL* fpCJV)(JavaVM**, void**, void*);
fpCJV JNI_CreateJavaVM = (fpCJV)::GetProcAddress(hJVMDLL, "JNI_CreateJavaVM");
JavaVMOption options[2];
std::stringstream ssoptions;
ssoptions << "-Djava.class.path=";
ssoptions << strcwd;
std::string stropts = ssoptions.str();
options[0].optionString = const_cast<char*>(stropts.c_str());
options[1].optionString = const_cast<char*>("-verbose:jni");
JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 1; vm_args.ignoreUnrecognized = false;
vm_args.options = options;
for (int i = 0; i < vm_args.nOptions; ++i)
{
std::clog << "Options[" << i << "]: " << options[i].optionString << std::endl;
}
JNIEnv* env; jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res != 0)
{
std::cerr << "C++: JNI_CreateJavaVM returned: " << res << std::endl;
}
jint version = env->GetVersion();
std::clog << "JVM Version: " << (version >> 16) << "." << (version & 0xffff) << std::endl;
return env; }
void CallClass(
JNIEnv* jniEnv,
const char* pszClassname,
const char* pszMethodname,
const char* pszSignature
)
{
jclass jvmclass = jniEnv->FindClass(pszClassname);
if (jvmclass != NULL)
{
std::cout << "C++: Found the class: " << pszClassname << std::endl;
jmethodID jmid = jniEnv->GetStaticMethodID(jvmclass, pszMethodname, pszSignature);
if (jmid != NULL)
{
std::cout << "C++: Found the method: " << pszMethodname << std::endl;
jniEnv->CallStaticVoidMethod(jvmclass, jmid, NULL);
std::cout << "C++: env->CallStaticVoidMethod complete" << std::endl;
}
else
{
std::cerr << "C++: Failed to find the method: " << pszMethodname << std::endl;
}
}
else
{
std::cerr << "C++: Failed to find the class: " << pszClassname << std::endl;
}
}
int main(
int argc,
const char** argv
)
{
const char* jreDir = nullptr;
std::clog.setstate(std::ios::badbit);
for (argv++; argc > 1; ++argv, --argc)
{
if (*argv[0] == '-')
{
if (strstr(*argv, "-d"))
std::clog.clear();
}
else
{
jreDir = *argv;
}
}
if (jreDir == nullptr)
{
std::cerr << "No root path provided for JVM." << std::endl;
return 1;
}
JNIEnv* jniEnv = NULL;
std::filesystem::path cwd = std::filesystem::current_path();
JavaVM jvm;
jniEnv = AttachJVM(jreDir, &jvm, cwd.string());
if (jniEnv == NULL)
{
std::cerr << "C++: Failed to get Java environment" << std::endl;
return 1;
}
CallClass(jniEnv, "CppToJava", "main", "([Ljava/lang/String;)V");
jint jvmres = jvm.DestroyJavaVM(); std::clog << "C++: DestroyJavaVM and terminate: " << jvmres << std::endl;
}
|
|
|
|
|
Can you include a project with this? I tried it inside a project with c++17 but I'm getting 29 errors.
It marks these lines as problems:
std::filesystem::path jvmpath(jrePath);
jvmpath /= pszjvmname;
if (!std::filesystem::exists(jvmpath)) {
std::filesystem::path cwd = std::filesystem::current_path();
jniEnv = AttachJVM(jreDir, &jvm, cwd.string());
Right now I'm using this to create a VM:
FString UCreateVM::createVM(FString location) {
std::string javaLocation = TCHAR_TO_ANSI(*location);
javaLocation.insert(0, "-Djava.class.path=");
javaLocation.append("Data/Java");
JavaVMInitArgs vm_args;
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = &javaLocation[0];
vm_args.version = JNI_VERSION_10;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = false;
JNIEnv* env = nullptr;
jint rc = JNI_OK;
if (jvm == nullptr) {
rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
}
else {
rc = jvm->AttachCurrentThread((void**)&env, NULL);
}
delete[] options;
if (rc != JNI_OK) {
if (rc == JNI_EVERSION)
return "JNI_EVERSION";
else if (rc == JNI_ENOMEM)
return "JNI_ENOMEM";
else if (rc == JNI_EINVAL)
return "JNI_EINVAL";
else if (rc == JNI_EEXIST)
return "JNI_EEXIST";
else
return "JNI_FATALERROR";
}
return "JNI_CREATED";
}
Also, I should mention that I'm using Eclipse Adoptium Java JRE , and it will be distributed with the app (with all the legal stuff), and in the above function I can add another parameter and tell it where the path for the dll is located inside the app/Eclipse Adoptium Java JRE folder.
modified 26-Jan-23 5:03am.
|
|
|
|
|
I think your option (c++17) may be incorrect, it should be as below. I don't use a project but a simple Makefile. The compile statement that it generates is:
cl -nologo -EHsc -RTC1 -W3 -std:c++17 -I "C:\Program Files\Java\jdk-18.0.2\include" -I "C:\Program Files\Java\jdk-18.0.2\include\win32" cpptojava.cpp
The include paths may well be different on your system.
Your code appears to be OK; what happens when you run it?
|
|
|
|
|
My code is running fine, but I just wanted to skip the step where you have to add the path of the jvm.dll inside Environment variable. Because with this, I need a separate exe file that will first check if the path is added or not (and to add it if it isn't), and after that to launch the exe for the program that is using JNI.
So for this right now I have a Java program that is doing the check and acting as a launcher (which is made using jpackage command, so it doesn't need Java to be installed), and when the check is done it is launching a different exe from its folder.
|
|
|
|
|
Looking at the code, is the following line really what it only needs and the rest are checks if it exists, if it was loader or not?
hJVMDLL = LoadLibraryW(reinterpret_cast<PCWSTR>(jvmpath.c_str()));
|
|
|
|
|
That just loads the library into the process's address space. You still need the dynamic calls to find the method addresses before you can call them, as the library is not linked to the application at build time.
|
|
|
|
|
Would AddDllDirectory with the path of the jvm.dll help with setting another path for the app to look into before it goes to Environment variables? Or that is used for something else and it won't work with JNI? Like I said, I can give the location to the jvm.dll in a parameter, because the location is different for each user, depending where the app is is installed.
|
|
|
|
|
JohnCodding wrote: Would AddDllDirectory with the path of the jvm.dll help I have never used it but the documentation suggests that it would. There's only one way to find out if it works.
|
|
|
|
|
I tried this, but it doesn't work.
std::string dllLocation = "C:\\Program Files\\Eclipse Adoptium\\jdk-18.0.1.10-hotspot\\bin\\server";
std::wstring temp = std::wstring(dllLocation.begin(), dllLocation.end());
AddDllDirectory(temp.c_str());
I also tried to switch it to SetDllDirectory but that also didn't work.
|
|
|
|
|
I might leave it as it is, with the launcher which adds the jvm.dll path to User path if it doesn't exists, and then to launch the actual app. C++ code wording is different then Java, more "raw", and I'm really not use to it, I'm getting lost looking at it and more confused the more I look at examples.
If it aint broke dont fix it.
modified 26-Jan-23 7:11am.
|
|
|
|
|
I just tried AddDllDirectory also, but it does not seem to do what I expected. I have also been going round in circles trying various changes but basically getting nowhere. I think you are right to stick with a solution that works for you.
|
|
|
|
|
Having used JNI multiple times before I would note that I would never use it again.
If the JNI code crashes then it takes the VM down. And there is little or nothing you can do to stop that.
For convenience I am going to refer to the needed non-java code as C/C++ below but it applies to any language that can be used to create an exe.
And there is a very viable option
1. Create a C/C++ wrapper which allows the target code to be run as and exe.
2. The exe has a control API. There are three ways to control it: Stdio, files or TCP/IP. Or perhaps pipes.
3. Use Java process API to run and manage the exe. That allows one to start, stop and kill it.
4. The Java code uses the control API to control it. This can include everything: configuration, passing binary data, statistics, health checks even a request for the exe to exit.
Advantages over JNI
1. It cannot crash the VM
2. The external code runs in its own process space.
3. The C/C++ code can be unit tested independently from Java code.
4. The C/C++ code is its own deliverable. Move the exe into the Java deployment space. It can even be packaged into a jar (any file can be) but of course it would need to be extracted into the file system.
5. The java code can be tested independently from the java code if the control interface is built carefully.
|
|
|
|
|
When you are running in Java:
ResultSet rs = stmt.executeQuery("SELECT Column FROM Table WHERE Condition");
Does the database create in memory a list with all the rows/values that have the given condition, and it is keeping that list until the rs is close? Or it will only keep the first value, and move to the next value when rs.next() is called?
I'm asking this because you can give it the command to FETCH NEXT X ROWS ONLY , and in case you have a database with millions of entries, that would save time and resources when you only want X rows, and not all of them that match the given condition.
Or the FETCH is only a hard limit to know when to stop with sending the rows/values one by one?
|
|
|
|
|
Valentinor wrote: SELECT Column FROM Table WHERE Condition
First keep in mind that is SQL. It is sent as is to the database.
Valentinor wrote: Does the database create in memory a list with all the rows/values that have the given condition
That is not how the jdbc is defined to work. But a bad driver could definitely do that. There is (or was) a jdbc/odbc 'text' driver and presumably it could have loaded everything into memory. But that was basically a toy anyways.
The next() technically loads it. But drivers I have actually looked at usually use some sort of batch request that might load 10, 100, etc, and then wait for the next to pull from the local set. I think I even recall somewhere that can be adjusted. The initial set as somewhat low value.
Valentinor wrote: FETCH NEXT X ROWS ONLY
How you do that depends on the database (see above). But every query you write should always be constrained (the where clause) and most should have a limit on the number of rows. The result should be paged.
Only time that would not be true when you know for a fact that the target table has an extraordinarily low growth factor. Only ones I know for sure like that are application enumeration tables.
Table examples where you should ALWAYS include the paging mechanism are things like customers, users, orders, events, etc.
Valentinor wrote: database with millions of entries, that would save time and resources when you only want X rows,
That is a complex statement and there is no simple answer.
You should NEVER, for example, allow for a design where a UI could expect a user to view 'millions' of rows. As a developer if you see a requirement like that you should insist that the requirements be changed to include reasonable constraint restrictions. Some examples
1. Require a date range, account number, customer store, etc.
2. Do a count(*) with the constraints in place and throw an error if the result is larger than X (say 10,000) which would then require the user (in the UI) to add more constraints to narrow the result.
And such queries should ALWAYS require a page and row size. So for example 'page 5', 'size 20'. The backend then restricts (hard code) the max size to something like 1000.
Additionally the users (whoever they are) might claim that they 'need' all of those rows. A person can never process millions of rows so such a claim for a user is ridiculous. The user in such a case always knows that they are looking for something very specific like a email, customer name, account number, etc.
However the other possible need is some automated process is going to consume that result. And in that case you should design a batching system that can dump large files wo some location (FTP server) to be processed by that external service. There are a vast number of problems that should be addressed in such a request, of which just one, is that you do not want to be dumping the entire contents of that table every day or every hour. Not to mention that there might even be some consideration about who actually owns that data and who pays for the processing to deliver it.
|
|
|
|
|
jschell wrote: That is not how the jdbc is defined to work.
OK, good. I'm the only developer for now, so I'm working on everything, and DB/SQL isn't something I'm good at, but I don't want to make a bad DB when it comes to performance.
jschell wrote: But a bad driver could definitely do that.
I'm using Oracle JDBC driver 11, so I would say that is out of the question.
jschell wrote: The result should be paged.
Is this a good example of paging?[^] Unfortunately, that isn't something I know of.
jschell wrote: You should NEVER, for example, allow for a design where a UI could expect a user to view 'millions' of rows.
Oh, no way that. By that I meant something else, but you answered it here:
jschell wrote: That is not how the jdbc is defined to work. But a bad driver could definitely do that.
Thank you for all the info!
|
|
|
|
|
Valentinor wrote: Is this a good example of paging?[^]
Using the following in google to look for examples.
PLSQL paging query
|
|
|
|
|
There's a phrase in TSQL parlance:
"Row by Agonizing Row"
(In order to give proper credit to the conspiracy that does the stabbing here I'd have to misquote someone so I'll just type in stuff which an eleventh grade high school teacher could type if she were quoting herself).
Look up INDEX and think "I'll use INDEX, in 'automatic assign of an index' and just DROP the original index and reassign it after I do all the tabulation"
|
|
|
|
|