How to check JRE version prior to launch? - version

What's the best way to determine if the version of the JRE installed on a machine is high enough for the application which the user wants to run? Is there a way of doing it using java-only stuff? I'd like the solution to work on Windows/Linux/MacOSX - if the JRE version is too low a message should be displayed. Currently I'm getting an exception if i try to run it on Java 1.5 (the app is built for Java 1.6). If there's no universal solution, what's the best way to do it on Windows?

You could do this using reflection and two compilers. Compile a main class with the oldest java version you want to be able to run at all with. It checks the version using System.getProperty("java.version"), or whatever, and then uses reflection to load your real main class if that check passes, possibly even loading the jar directly. The JRE shouldn't load any classes that weren't referenced by your outer main class at compile time.

You might consider Java Webstart. Even if the name implies something like applets, it's about standalone-applications. Webstart is a launcher, that checks a JNLP-file (a simple XML-file, where you configure the download-location of your app, the needed Java-version and some other metadata) and starts your app with the correct JRE. It even updates the application, if a newer version is available. The downside is, you have to write a JNLP-file. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<!--
###############################################################################
#
# #(#)draw.jnlp 1.6 02/09/11
#
# JNLP File for Draw Demo Application
#
###############################################################################
-->
<jnlp spec="0.2 1.0"
codebase="http://java.sun.com/javase/technologies/desktop/javawebstart/apps"
href="draw.jnlp">
<information>
<title>Draw 4 App</title>
<vendor>Sun Microsystems, Inc.</vendor>
<homepage href="http://java.sun.com/javase/technologies/desktop/javawebstart/demos.html"/>
<description>A minimalist drawing application along the lines of Illustrator</description>
<description kind="short">Draw Demo Short Description</description>
<icon href="images/draw.jpg"/>
<offline-allowed/>
</information>
<resources>
<j2se version="1.3+" href="http://java.sun.com/products/autodl/j2se"/>
<j2se version="1.3+"/>
<jar href="draw.jar" main="true" download="eager"/>
</resources>
<application-desc main-class="Draw"/>
</jnlp>
A second possibility is to use a launcher-program. An example is the Apache Commons Launcher. You can also write some launcher app yourself, but that's usually not worth the effort.

You might also consider using Commons-Launcher, which allows you to setup various environment settings, or perform pre-checks before calling your application.
http://commons.apache.org/launcher

Generally, we've approached this with a C or (when unix-only) shell wrapper. Not sure this will really work for you.
We also approach this by embedding the JRE in our product. Takes care of 99.9% of the cases (the other 0.1% of the time is a user explicitly changing our configuration to use a different JVM). Again, not sure that this is a reasonable solution for you.
In our case, there is significant amounts of native code (JNI and otherwise), so tailoring an installable image for each platform we support is required anyway. But if you're dealing with a pure-Java solution, you may simply have to document your minimum and tell people to get with the program (no pun intended) if they're to run your stuff. It's sorta like people complaining that my Mac won't run MSVC, or that my Linux box is having problems running World of Warcraft. That's just not the (virtual) machine the software is targeted for - you need to switch. At least in the Java world, we really can call this an upgrade, though, without hurting anyone's OS-religious feelings. (Try telling the Mac user to "upgrade" to Windows XP to run MSVC - there's a beat-down waiting to happen.)

You can require a Java version when running the Java command, e.g. java -version:1.6* com.me.MyClass. Not sure if this works on all releases of Java, but it works OK on 1.6 anyway.

An application built for a higher-version JRE will not run on a lower-version JRE. So you wouldn't be able to just add code to your application to check the JRE version - if the JRE version was incompatible, your JRE-version-checking code would not run in the first place.
What you'd have to do is have some sort of launcher application that is built for a lower-version JRE (1.3?) that checks the version and then launches your app if necessary. This sounds kind of kludgy to me.
What about checking the version during installation? Are you installing the app in a way that allows you to check environment variables, or do any sort of scripting?

For the launcher - Check the version in there.
Inside the APP; as above use System.getProperties();
Properties sProp = java.lang.System.getProperties();
String sVersion = sProp.getProperty("java.version");
sVersion = sVersion.substring(0, 3);
Float f = Float.valueOf(sVersion);
if (f.floatValue() < (float) 1.4) {
System.out.println("Java version too low ....");
System.exit(1);
}
...

Have a launching class compiled for Java 1.2 which invokes the real main() in your 1.6 classes. If an unsupported class exception is thrown them catch it and display a nice error message.

Here is the code to get the JRE version installed in a system.
var list = deployJava.getJREs();
var result = "";
result = list[0];
for (var i=1; i<list.length; i++)
{
result += ", " + list[i];
}
document.write("jre version : "+result);

System.getProperties() gives you a listing of JVM properties including the different version ids of the JRE, JVM and specification. This implemented for all versions of Java so should work regardless of version compiled in and version run in, or the implementation.
If you write a basic class to test the version, you can call this first in your main() launching class. It must really be basic functionality though or you might risk breaking it.

Hmm .. call me a boring guy, but what's wrong with using Launch4J or any other native launcher, for instance.
Use a native launcher to check the JVM version before actually running your code. Java only solutions (in my book) only make sense when you deal with developers; once you hit end-users, you'll realize that they dont care about Java or its technical details at all. If you would have written your application in GW-Basic they would not care less as long as your application works.
If Java 1.6 is not installed, lauchner4j will point the user to the download page for JDK 1.6. Thats probably more suitable for your problem than doing magic in Java.

I find that WinRun4J works quite well for me (but then again I may be biased since I wrote it:-)). This lets you specify a minimum and/or maximum version of java allowed. It will pop up a message box to the user if a suitable JRE version is not found (and the message is customisable).

All those above is too damn complicated.
Just go:
Properties props = System.getProperties()
props.list(System.out)
And you will see everything about your JVM, JRE, JDK and staff.
Or get a specific value by using:
//full list of possible props you can see if u run code above
String props = System.getProperty(prop)

Related

.NET: How to isolate an anti-debugging class library?

I built a .NET class library and used an obfuscator to obfuscate it with anti-debugging.
I built a testing project using my obfuscated class library. I would have hoped that anti-debugging forbids debugger to step into my class library. But it simply threw exception "Debugger detected" when my class library was invoked when I started the project in debugging mode (by pressing "F5" in Visual Studio).
What this means is that if a project uses my library then the developer simply cannot debug at all. They may have millions of lines of code that has nothing to do with my library. Not being able to debug at all in their project will only mean one thing: they will not use my library.
Is there anyway a developer can do to "isolate" my library, so that they can debug elsewhere?
Specially thanks to #Artem Razin for:
isolate sensitive code to a separate process that runs with the
enabled anti-debugging feature.
Its great and helpful. Also virtualization he specified is good approach. I will post you a good approach if you need exactly working with anti-debug envirnoment. Bceause you mention the exception: Debugger Detected
Am assume you use Eziriz .NET Reactor. When I speak with support. They said you can't provide two anti-debug version for specific HardwareID. Because HardwareID involved in the licensing system and it must not bypassed!
I can tell you a workaround for that by using .NET Reactor CLI and MSBuild targets.
What scenario it should be? (I will show what we need to do before write CLI...)
If you a have a developer team, or friend who need to use your obfuscated library. That's great. But he can't debug because its anti-debugged.
Then we must separate an assembly into two assemblies. One for developer its obfuscated but without anti-debug feature enabled. and other assembly into release folder for consumer or your audience.
So when you build your assembly. or need to create nuget package for it. you need to do a double obfuscation. Firstly you will obfuscate the anti-debug version for consumer into Consumer/AntiDebug folder. Secondly you will obfuscate the original DLL again but for developer without anti-debug feature!
So please use Directory.Build.targets for that. Here's code for obfuscation:
<Target Name="ObfuscateDLL" Condition="'$(Configuration)' == 'Release' AND $(OutputType) == 'Library'"
AfterTargets="AfterBuild">
<PropertyGroup>
<ObfuscatedFolder>$(MSBuildThisFileDirectory)\Anti Debug</ObfuscatedFolder>
<ObfuscatorPath>C:\Program Files (x86)\Eziriz\.NET Reactor\dotNET_Reactor.Console.exe</ObfuscatorPath>
<ObfuscatorParameters>-antitamp 1 -anti_debug 1 -hide_calls 1 -hide_calls_internals 1 -control_flow_obfuscation 1 -flow_level 9 -resourceencryption 1 -antistrong 1 -virtualization 1 -necrobit 1 -mapping_file 1 -mapping_file_overwrite 1 -mapping_filename "<ProtectedAssemblyLocation>\<AssemblyName>.nrmap" </ObfuscatorParameters>
</PropertyGroup>
<!-- Obfuscate with anti-debug to Obfuscated folder or \Release path when GenerateNuget enabled -->
<Exec Command=""$(ObfuscatorPath)" -file "$(TargetPath)" -targetfile "$(ObfuscatedFolder)\$(TargetFileName)" $(ObfuscatorParameters)"/>
<!-- Obfuscate without anti-debug to /Release path for Nuget package for Developers -->
<Exec Command=""$(ObfuscatorPath)" -file "$(TargetPath)" -targetfile "$(TargetPath)" $(ObfuscatorParameters.Replace('-anti_debug 1','').Replace('-mapping_file 1', ''))"/>
</Target>
Please use above code! if you need it as simple as possible. But you need to manually create nuget package for you developer. via MSBuild or by the way you need.
But If you use .NET Framework and want to generate obfuscated debuggable nuget package (for developers). And also provide anti-debug version to your consumer. You can use following MSBuild targets.
It contains ability to create Nuget package with all dependencies automatically.
It obfuscate the consumer library to Anti Debug folder. then It will obfuscate nuget version and packacking it. then copy back Anti Debug version to Release folder.
You can manually turn on/off GenerateNuget property. If you will not generate nuget so anti-debug version only produced.
Change the code depending on your needs...
https://pastebin.com/wmvcWMUp
(See link XML content are large can't posted to StackOverflow)
Anti-debugging is a well-known feature since the times of exe packers. Unfortunately, it is a process-wide thing. Usually, .NET obfuscators check debugger-specific environment variables.
There is no way to prevent a debugger from stepping into your assembly.
I would say that anti-debugging is for those who want to protect their end-user products, not libraries.
You can virtualize your code (modern obfuscators like ArmDot provide this feature), so debugging it would have almost no sense.
Another idea is to isolate sensitive code to a separate process that runs with the enabled anti-debugging feature. On the client-side, you just provide a proxy that redirects all calls to the process.

How do I copy my Selenium project from one laptop to another?

I have developed a hybrid framework using a maven project, POM, TestNG, etc. It's running fine now I wanted to copy the entire project from one laptop to another laptop so on first laptop I can continue with my work and second laptop I can use it just to execute the scripts which will same my lot of time.
On daily basis I take backup on OneDrive. I have some questions:
Can anybody guide me how to copy the entire project? Do I need to have the same version of Java and Eclipse on second laptop? Anything else need to be installed?
On a daily basis how do I get the backup data from 'OneDrive' to a second laptop?
This sounds like you want a repository. Use Github, Gitlab, Bitbucket, just.. git in general. That's exactly what this is for.
As for your Java and Eclipse versions, you need to look at your running version of selenium, what packages you are using, etc, and determine for yourself what Java version you should be running. The latest version of the jdk is going to have everything the earlier ones had, so it's usually a safe bet to use the latest stable version. Your Eclipse version should always be the latest as well as it is just an IDE and shouldn't have any impact on how your program runs.
Another option is to use a virtual environment (a virtual-env) and upload that to your git repository, this is a localized version of java present inside the project, that can be carried along with it, although this bloats your repository massively.
Try using git and github and you don't have to take backup and need to work on a specific laptop

Setting up a workflow for autoformatting a git repository (C)

I want to set up a workflow that allows me to have a git repository with a uniform/consistent formatting. The developers (approx. 30) should be able to commit properly formatted changes to their local repository easily, independent of their operating system (either some Linux or Windows 10) and independent from their IDE. Changes shall be pushed to a Linux server which administrates the remote repository.
From my point of view there are two steps necessary to ensure that the remote repository is properly formatted:
Format the current state of repository according to a set of rules.
Format the files affected by every new commit according to these rules.
The first step can be implemented easily by running an auto-formatting tool (e.g. clang-format) on the complete repository. The implementation of the second step can be further divided into two substeps:
2a) Client side: Format a commit properly before pushing it to the server.
2b) Server side: Check if the repository will be properly formatted after the changes of the commit are applied.
The second substep (2b) can be implemented easily (simlar to step 1). However, the implementation of the first substep (2a) is more demanding and I would like to reach out to the community for tipps/tricks/ideas.
So far I've had a closer look on the Eclipse autoformatter and clang-format:
The Eclipse autoformatter can only be used when Eclipse is installed, I haven't found a Eclipse autoformatter standalone application. Is it possible to run the eclipse autoformatter from the command line without a GUI?
clang-format is a unix tool which I cannot install and run standalone on a windows system. I've seen there is a LLVM executable for windows but I am not sure if the installation will inflict any undesired changes to my system. Is anybody using LLVM/clang-format on windows?
Are there other auto-formatting tools for C which work on Linux and Windows 10? Is anybody successfully using python scripts for this purpose?

How to use shp2pgsql

My question should be very simple to answer for anyone not being a self-taught newbie like me...
On this page is a cheatsheet concerning a function to be used in GIS/DB environnement : http://www.bostongis.com/pgsql2shp_shp2pgsql_quickguide.bqg
I would like to create a script allowing users to just have to click on it to launch the process, given the proper datas. But I don't understand how to use this. It obviously doesn't work in a Python console, nor directly in the windows console. How is it supposed to work ? What language is this ?
Thanks
shp2pgsql is indeed a command line tool. It comes with your PostgreSQL/PostGIS installation (usually) and, if not accessible via PATH-variable, can (usually) be run from within the /bin-folder in your PostgreSQL-Installation. You can also always 'make' the programm from source in any location yourself, if needed.
EDIT:
One way to set up a script (independent of whether you use it within qgis own python environment or not) would be to use Pythons subprocess (or os.system) module (check related question here) to write to shell and execute shp2pgsql.
A slightly more sophisitcated solution to (batch) insert (multiple) shapefiles via script could be to implement ogr2ogr via gdal/ogr module within python (check this blog). That, however, would require a working installation of the gdal core library, and the respective Python bindings (at least to use outside of QGIS Python environment, where it is pre-installed AFAIK), which can be tiresome at times. Once installed correctly, it offers a powerful (I dare say almighty) toolset for geodata management and manipulation via Python, though.
Apart from that, the blog link I provided also states the implementation of a batch insert script/tool (which operates ogr2ogr) in qgis 2.8 toolbox...maybe that can help you, either with your work directly or (via sourcecode) to point you in the direction of creating your own tool.

BDE Installation: there is not enough space on drive c. install to this location anyway

I am trying to install BDE Engine by executing the following command line from my installation program as follows.
ShellExecute(0, nil, 'regsvr32.exe', 'BdeInst.dll', nil, SW_SHOW);
It pops up with a message requesting permission to install BDE Engine at a particular location. When you click okay button, it pops up another a message as follows.
I did verify that I have plenty of free space in my hardrive. When you click on Yes button, it installs the BDE engine successfully.
I don't know why. Plus, there is not much information online about this.
Any input will be greatly appreciated.
First of all, the BDE is deprecated, and you should better avoid using it, even with other versions of Delphi.
You have third party components around able to connect directly to DBs without using the BDE. See e.g. DevArt, SQLDirect, DASoft (its FreeDAC is free), and a lot of other components like Zeos or our SynDB Open Source libraries.
You reached the well known "2GB rounding error". The BDE installer suffers from it, but applications using BDE also.
BDE installer is buggy.
It just does not work with newer versions of Windows.
You have other installers around, like interbase and BDE on windows 7 or Bde Installer on these Embarcadero days
BDE used in applications will suffer from the same 2GB limitation, linked to the GetDiskFreeSpace improper use.
There is a work around available on Embarcadero CodeCentral which is worth to be included in your application code.
The BDE is an old piece of software that has now been deprecated for a few years. While people do still have it running, I believe it was originally 16bit software and may never have been changed. I have a feeling the message is coming from some piece of software that can not understand your large hard drive. I don't recall if BDEInst.dll is the BDE installer from Borland, but the message may be coming from that. You also mention an "Installation program is being developed ...".
It should install to XP, and I would get it working there first. Win 7 and 8 introduce more issues. However, if at all possible, reconsider if you want to install BDE at this point in time.
The bdeinst.dll uses the Win32 API function GetDiskFreeSpace, which can report a completely misleading value when executed against a drive that is larger than 2GB - see http://support.microsoft.com/kb/202455 for a developer-based workaround.
The reason I know this is because I've been hit by it before and examined the imports for the bdeinst.dll binary which indicates that it uses GetDiskFreeSpaceA (this is the ascii version of function).
If you have to use the BDE, then you just have to accept that you may see this error when you attempt to install the app

Resources