In PHP, we have:
<?php include 'external_file.php'; ?>
Whereas in Java, you have imports:
import javax.servlet.http.HttpServlet;
It is to my understanding that PHP includes simply dump the contents of the external file into the file that contains the include statement.
My gut feeling is that Java handles these includes/imports differently than PHP. What are the key differences?
PHP's include is pretty much the exact same thing as having literally cut/pasted the raw contents of the included file at the point where the include() directive is.
Java's compiled, so there's no source code to "include" - the JVM is simply loading object/class definitions and making them available for use. It's much like the #include directives in C. you're not loading literal source code, just function definitions/prototypes/fingerprints for later use.
In php it simply dumps the contents of the file in the current file.
In Java, an imported class is used:
For compiling the source to byte code using the imported classes.
At runtime when the JVM sees that your program references the imported class, it loads it and uses it(for method invocations and member accesses if it is the case)
PHP simply just includes whatever is in that file. It's simply merging the two files together.
Java's import function gives you access to the methods specified in that import. Basically, PHP is just a rudimentary combining of the two files while Java gives you access to that file's methods and interface.
You have <jsp:include> in Java similar to PHP include.
Java import is similar to PHP load module.
The closest to a php include in Java is a static import. I.e. something like: import static javax.servlet.http.HttpServlet. This allows you to reference methods in the same class file as if they were declared locally (this only applies for static members of the imported class. However, this is very seldom used. It's a tighter form of coupling and should be avoided in most cases. The only time I find it helpful is for Junit test cases. Doing a static import of org.junit.Assert allows you to use the shorter form assertEquals(...) instead of Assert.assertEquals(...). Check out Oracle's documentation on static imports here.
The main difference from my experience is that PHP allows you do do anything. You can treat PHP includes the same way as Java uses its imports. A PHP file can be all function, or it can simply execute from start to finish.
So your php file could be
<?php
echo(1 + 4)
?>
or it could include function which you call later on
<?php
function addTwoNumbers()
{
return 1 + 4;
}
?>
If you inccluded the second php file you could call the addTwoNumbers function below your include statement. I like to practice specifying individual functions rather than create many PHP files.
They are very different. Php just include the source code from the included file.
Java is using the ClassLoader to load the compiled class located somewhere in the CLASSPATH. The import just tells the compiler that you want to reference those classes in the current namespace. The import does not load anything by itself, only when you use new, the JVM will load the class.
Related
I've been trying to find an answer to this for some time, but I think part of my problem is that I don't really know how to phrase my question. I understand the that JVM ultimately preforms all the system calls at run-time that the Java program needs to make, my confusion is about the underlying way that Java classes tell the JVM to do this.
Take for example, the File class in the standard Java library. As far as I know, this is considered the most fundamental API for opening/creating files in Java. But, File is just another class right? So in theory I should be able to write my own File class from scratch which doesn't utilize the pre-exisitng one, right? How would I do that? What is happening inside the File class that tells the VM to actually create the file? I looked at the source code for the File class, and it looks like it calls another class called VMFile, but I could find no explanation of what VMFile is. When I looked at the VMFile source code, it just had function declarations with no definitions.
Thank you for your help.
The Java Native Interface (JNI) is the glue between Java classes and the OS. Native methods have a 'native' attribute (look it up in the JLS).
I have a jni dll that has functions being called from java. The problem is that this dll has all the java classes in the default package (in the dll "Java_classname_methodname"). It is impossible to get the source of this dll and it would take EXTREMELY long to rewrite. So I basically need to call the functions in this dll from java in a different package than default. I've tried for hours on end to rename the functions in the dll with a hex editor and several tools to modify the checksum and addresses in the dll but it's just too much for me because I have almost no experience with this. I would very much prefer this route, but I just don't have the proper tools or the know-how. So what I'm left with is trying to hardcode the package name in java. I tried using jna as described in this stack overflow post to do something like this:
Map options = new HashMap();
options.
put(
Library.OPTION_FUNCTION_MAPPER,
new StdCallFunctionMapper() {
public String getFunctionName(NativeLibrary library, Method method) {
method.setName(method.getName().replace("com.test.", "");
return super.getFunctionName(library, method);
}
}
);
Native.loadLibrary(..., ..., options);
But there is no setName in Method. Ideally I'd like to get this done without any extra libraries but I'm obviously not opposed to using something like jna. And before anyone asks, yes this is permitted by the library's usage license. Please don't tell me it's not possible because know that it's possible, just difficult. Whichever way it must be done I am willing to put in the work (either modifying dll or using java code with some external library). And by the way, I also need this done on .so and .dylib files eventually (not as important as dll). Thank you for your time.
I have a JNI dll that has functions being called from java. The problem is that this DLL has all the java classes in the default package (in the dll "Java_classname_methodname").
So the corresponding Java class with the native methods wasn't in a package either.
It is impossible to get the source of this dll and it would take EXTREMELY long to rewrite. So I basically need to call the functions in this dll from java in a different package than default.
Correct.
I've tried for hours on end to rename the functions in the dll with a hex editor and several tools to modify the checksum and addresses in the dll but it's just too much for me because I have almost no experience with this.
You may be able to alias the function names somehow, but it's been about 20 years since I practiced in this area.
I would very much prefer this route, but I just don't have the proper tools or the know-how. So what I'm left with is trying to hardcode the package name in java.
No. There is no package name to hard-code. What you're left with is trying to call native methods in a class without a package from a class in a package, which since 1.4 is not possible.
What you need to to do is either:
It is possible to call the package-less Java native methods via reflection. So, you can write a wrapper class that does that, which lives in the package of your choice, and the rest of your code can call the wrapper.
Or
As follows:
Write another Java class in the package of your choice with the appropriate native methods.
Create an import library from the existing DLL.
Write another DLL and link it with this import library.
Load this new DLL from your Java code.
Have this DLL use the RegisterNatives method on initialization, to register the existing JNI entry points in the old DLL under the new native method names & signatures.
Use javah to get the required native method names and javap to get the required Java signatures. Don't try to guess them by hand.
Don't ask me how this maps to .so files.
I'm very new to java, actually just started using it today because we're developing for an Oracle database and we need to let it run java code.
I've been adding a simple project, like this, without problems:
public class Test
{
public static string Result()
{
return "Test successful!";
}
}
I can load this into the database and access it with PL/SQL.
However, when I upload the class I actually need it is marked as "INVALID" in Oracle.
I think this is because of missing references in java, for example, i have these imports:
import java.text.SimpleDateFormat;
import java.util.Date;
I think the problem is that my Oracle database is missing the required DLLs (actually the java equivalent for that).
Now, is there any way for me to compile my java class and include all the references I have stated in my class definition?
Thanks a lot!
All Java compilers put the import statements into the .class file. There is nothing you need to do for this. But they don't include the classes which are imported. So it's your responsibility to make sure the Oracle DB server can access any custom classes.
The Oracle database server comes with a standard Java VM, so all types below java.* should be visible when you upload Java code to be executed on the server.
Other types may be missing. Read the documentation, there should be an explanation how to upload a JAR archive with all the classes that you need. Then create such a JAR and upload it (instead of uploading just a single class file).
I think Aaron Digullas answer was the closest one, it looks like the Database already has access to the standard java classes.
Actually, I'm sorry, I think I have made a mistake with importing java.
I can access the Database with SQL Developer and directly enter my source code there to insert a new java class in my database, everything works then.
It looks like I have either made an error when compiling the class or when using the "loadjava" command to insert the java class in the database.
I'm writing a C++ dll (file extension in Visual Studio is .cpp but the code is C) which uses JNI for loading and calling instance methods of some Java classes. As a result my project is made up by C++ source and header files plus some Java class files (the class files for the Java objects used through JNI). I would like to create a single dll library including also the Java class files "in a single bundle". Is it possible to put both the C and Java files into the dll?
This is perfectly possible, though not necessarily intuitive. I haven't tested this but I would imagine it would work easily if you knew what you were doing.
First off, you're going to need a way to package the class file's binary into the native binary you own, and then of course be able to seamlessly read that chunk at any point in time. How you achieve this is up to you, there is no real 'right way' to do it.
That being said, if you can get a handle to the memory where the .class file's data resides (after loading the DLL) and pass it to Java as a byte[] or ByteBuffer, you'd then want to use any one of ClassLoader's defineClass overloads along with a call to findLoadedClass and then finally loadClass.
This would allow you to load in a class from virtually any data source. As I mentioned before, how you store/retrieve the native data for the class is up to you.
In C, there is this concept of header files that lets you include the header files required for most of the program in one go and so you can only import that one header file in each of your program. I find this pretty neat. Now, I have been working in JAVA for a while and afaik I cannot group together a set of imports that I require for almost every file and put them in one. Am I wrong? And is this better than putting all the required bunch in one java file.
There's no such thing. If you require a class from another package (that isn't in java.lang), you'll have to import. But that's practically trivial when using a proper IDE. In Eclipse or NetBeans, you're usually one key combo away from fixing your imports.
There's no equivalent to header files in java, however you can import whole packages:
import mypackage.*