I'm currently developing a GUI for a Java-application that I've created. I would like to keep the GUI in a separate process from the rest of the client. The rationale behind this is:
Reduced risk of crashing. E.g. a OutOfMemoryError in the GUI won't crash the rest of the client.
I get an API "for free". If I later on want to allow other people to programmatically access the client I can just let them use the same API that the GUI is using.
I'm writing the GUI in SWT and the client is created using IntelliJ. Since Eclipse has a lot better SWT-support it makes sense to keep them separate, so that I can use Eclipse for the GUI-code and IntelliJ for the rest.
My question is now: what technology should I use to expose the client's interface to the GUI? RMI is what came to mind first. However, that has the disadvantages of restricting the API to be Java only. I'm also not sure about how well suited RMI is for large scale deployment (e.g. how does it handle local firewalls?). However, I don't want to rule it out just yet.
I should also mention that I have some deployment-requirements as well:
Must be able to run as non-admin.
Must be able to handle restrictive local firewall-restrictions.
Deployment must be automatic (it's a large scale consumer-app) and work on Windows, Mac OS X and Linux.
Given these restriction what solution would you use?
I faced this same situation a while back, except that the back-end was in Python, and the GUI was in java.
Important points to consider:
how flexible and granular the interface between the GUI and the back-end needs to be. Do you want to be able to do one thing from the GUI? 5 different things? 10? 50? How tightly coupled is the GUI -- will it know about/be calling individual methods in the back-end?
how the output gets from the back-end to the GUI. Can it simply write to STDOUT or to temp files? Does it need something more elaborate?
the format of the output. Ideally, it should be easily parseable, which indicates XML or JSON may be your best bet.
You might find JSON-RPC useful: it's a standard for remote method calls to separate programs.
All in all, it's hard for me to say what would be best for you. I ended up avoiding RPC, and gave the back-end a simple command-line interface; output was written to temp files and STDERR, as JSON objects. I feel that this was a good decision because it kept the interface between the programs very simple and uncoupled.
Related
I have a legacy web application sys-1 written in cgi that currently uses a TCP socket connection to communicated with another system sys-2. Sys-1 sends out the data in the form a unix string. Now sys-2 is upgrading to java web service which in turn requires us to upgrade. Is there any way to upgrade involving minimal changes to the existing legacy code. I am contemplating the creating of a code block which gets the output of Sys-1 and changes it into a format required by Sys-2 and vice versa.
While researching, I found two ways of doing this:
By using the "requests" library in python.
Go with the java webservices.
I am new to Java web services and have some knowledge in python. Can anyone advise if this method works and which is a better way to opt from a performance and maintenance point of view? Any new suggestions are also welcome!
Is there any way to upgrade involving minimal changes to the existing legacy code.
The solution mentioned, adding a conversion layer outside of the application, would have the least impact on the existing code base (in that it does not change the existing code base).
Can anyone advise if this method works
Would writing a Legacy-System-2 to Modern-System-2 converter work? Yes. You could write this in any language you feel comfortable in. Web Services are Web Services, it matters not what they are implemented in. Same with TCP sockets.
better way to opt from a performance
How important is performance? If this is used once in a blue moon then who cares. Adding a box between services will make the communication between services slower. If implemented well and running close to either System 1 or System 2 likely not much slower.
maintenance point of view?
Adding additional infrastructure adds complexity thus more problems with maintenance. It also adds a new chunk of code to maintain, and if System 1 needs to use System 2 in a new way you have two lots of code to maintain (Legacy System 1 and Legacy/Modern converter).
Any new suggestions are also welcome!
How bad is legacy? Could you rip the System-1-to-System-2 code out into some nice interfaces that you could update to use Modern System 2 without too much pain? Long term this would have a lower overall cost, but would have a (potentially significantly) larger upfront cost. So you have to make a decision on what, for your organisation, is more important. Time To Market or Long Term Maintenance. No one but your organisation can answer that.
Maybe you could add a man-in-the-middle. A socket server who gets the unix strings, parse them into a sys-2 type of message and send it to sys-2. That could be an option to not re-write all calls between the two systems.
I'm a pretty skilled java programmer that has dabbled in web development but I find that I'm much better at doing desktop based stuff than I am at anything related to web development. I've been trying to find an easy way of porting some of my desktop apps to run in browser but can't seem to find anything. I guess what I'm looking for is something similar to an applet but they a largely unsupported and get more buggy by the day. Is there anything similar that would allow me to keep my desktop style mindset and still run in browser or should I just break down and rewrite the whole thing in rails or another common web platform.
Java WebStart has been mentioned by others - It's a technology that aids redistribution of Java applications that then have the full rights of desktop applications, but they also have auto-update support built in. It's basically a launcher that fetches a JAR from the internet and runs it as a desktop application. These don't run within the browser.
Applets are an old technology that can be embedded directly into the web-page. They are not buggy, but they have several security restrictions. Also, the support is steadily declining because of the amount of critical bugs found in the technology. Desktop users that want applet support typically don't have trouble ensuring it, however. Currently, both the Chrome and the Java platform itself issue a warning before an applet is allowed to run - and that assumes the Java Runtime Environment is already installed.
Google Web Toolkit is a framework that allows creating single-page applications in Java, which are then compiled to Javascript. GWT handles multiple things behind the scenes, including server-client communication, localisation and internationalisation, and its own layout engine.
When translating an existing application to GWT, you need to:
separate the code into a part that runs on the client and a part that runs on the server. The server does not have direct access to the user, and the client does not have direct access to the database. If your application does not use centralised storage, it probably can run entirely within the web browser. Since client-server communication happens over the internet, you should reduce it to the minimum.
translate the front-end to GWT widgets. Forget Swing or AWT - they are impossible to compile efficiently to Javascript.
remove dependency on other Java classes that the GWT does not know how to translate into Javascript in the client part of the application. A large part of java.util. is supported but none of javax. (as of Jan 2014). The GWT site hosts the list of supported Java classes. Also, Javascript's regexes are less powerful than those of Java. Lookbehinds, in particular, are not supported. The server-side is a full-blown Java environment, but remember - you want to reduce the server-client communication to the minimum.
But, the most common strategy is to code the client side directly in Javascript.
Javascript is a language very similar in syntax to C/C++ and Java. It uses curly braces to denote blocks of code, and it uses semicolons to separate statements (though Javascript features automatic semicolon insertion, sometimes it understands two lines as a single statement if the first line is not terminated by a semicolon. Its data types include numbers (double-precision floating point), strings, booleans, two types of null, plain objects (which are basically hash-maps [string -> x]), arrays (untyped and dynamically extensible), regexes and functions (named or anonymous), all of which have their own literal syntax.
When coding in Javascript, your mindset should be:
Javascript is single-threaded and event-driven. You don't have to worry about concurrency issues, but you cannot say "now wait for x" either. Since Your Java code should be event-driven as well, this should not be an issue.
Lots of things in Javascript are asynchronous. Want to know something from the user? You should paint a dialog, and attach event handlers to its components. Want to get the user's GPS position? Ask for permission, passing it an event handler for when the user decides if the permission should be granted, from which you ask for the position, which also takes an event handler as an argument. Talking to the server? Asynchronous. Do you want to display something before doing a long calculation? You have to actually wait a little before you start computing. Ecmascript 6 improves the syntax a lot, but it's not yet supported in modern browsers.
Browsers only let you do so much. Disk access? Only to a file or folder the user explicitly points to. Clipboard access? The only reliable way is copy/paste into a textbox. Talking to a foreign webserver? Only if that webserver explicitly lets you (and lot of them don't even know how to). Of course, "foreign" includes a different sub-domain, different port number or a different protocol (http:// or https://). Desktop notifications? Geolocation? Ask for permissions first. Java applets have comparable security restrictions, and for the very same reason.
In Java, everything is a class. In Javascript, you can enjoy bare functions without any class. A typical event handler is just an anonymous function that you pass as an argument to a library function. Also, you can have anonymous objects using a very conscise syntax. This makes Javascript code much denser than that of Java and with very few classes, if any. Object Oriented Programming is still possible in Javascript, but much less pronounced.
When layouting your display, you need to think in terms of HTML and CSS. The best approach is to modify only the document structure (adding/removing elements or HTML classes) using the Document Object Model (DOM), and leave all CSS in an external file. In any case, you need to know CSS enough to be able to layout your page. Modern browsers support canvas, but it has no built-in layouting engine - its closest Java relative is JCanvas - just a blank area where you can draw graphics primitives - or a WebGL canvas - where you can place triangles in a 3D space.
When designing your own API, you need to know which operations might need to be asynchronous. If they are, either take a function as an argument (a callback), or return an object that does (a promise).
Except for the this variable, Javascript is function-scoped and lexically scoped and has closures. If a variable exists in a surrounding scope, it can be read from and written to - even from within a function that is only defined in that scope and called much later. In Java, you can't close over non-final function-local variables.
However, you need to be careful about timing - don't think you can just assign to a variable within a callback and use it outside. When you try to use it, it won't have been assigned to yet. Many have tried to cheat the time this way, and failed.
When the user leaves your page, it's a game over. If you want to remember anything past that point, you need to store it somewhere, be it cookies (very little space, outdated API), localStorage (decent amount of space, not supported by very old browsers) or the server (lots of space, but talking to the server when your page is being shut down is tricky).
the DOM API is often criticised, but there are several frameworks and libraries that ease the usage of it, of which the most popular is jQuery, which also handles browser inconsistencies, improves the AJAX API, event delegation (you can't attach an event handler to an element that doesn't yet exist) and includes an animation engine (though modern CSS is almost as powerful and often easier to use).
I think java web start could help you
http://www.java.com/it/download/faq/java_webstart.xml
I suggest you to take a look at Java Web Start. It offers you a possibility to start your application software for the Java Platform directly from the Internet using a web browser.
For more details see: Java Web Start
Nowadays Web Start is not a good option since, the user needs to have JVM installed and with all the vulnerabilities buzz around Java is more difficult to convince users to download it. The latest versions of JDK 1.8+ include scripts to pack your application along the jvm runtime in just one installer: https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/
For using your application in a browser like an applet, you can use Bck2Brwsr or TeaVM both can run java applications in a browser without Java Plugin. Bck2Brwsr also uses Java Plug in if it is available.
You can also use GWT to compile your Java application to JavaScript. Note: Swing is not supported.
Regards
Our company uses an IBM iSeries for a majority of our data processing. All of our internal apps are written in RPG. According to IBM's roadmap, IBM is pushing companies to move to Java/J2EE. We're looking to modernize our internal apps to a more GUI interface. We provide an external web presence by using Asp.Net webs, although perhaps greenfield projects could be Java. One option is to use a screen scraper app while staying on RPG but I think it may be better to slowly go the way of IBM's roadmap and move to Java. Our goal is to migrate to a GUI interface and to be inline with IBM's roadmap.
Have you been involved with an RPG to Java migration, even if only greenfield projects were Java and the brownfield projects remained RPG?
My management is afraid that:
1) updating JRE on workstations, particularly thin clients, could cause an administrative nightmare (Our company uses 80% thin clients and 20% PCs) and
2) Java demands too much overhead of the workstation to run effectively
3) Incompatibility between JRE clients as we update, potentially breaking other apps requiring the JRE.
Can you shed some light on this? Are there any huge benefits? Any huge gotchas?
CLARIFICATION: I am only interested in a migration to Java. What is the difficulty level and do I lose anything when going from RPG to Java? Are the screens very responsive when migrated to Java?
My company is also attempting to migrate to Java from RPG.
We're not attempting to use a JRE on a thin-client, we're moving to web applications delivered through a browser. This may entail (eventually) replacing our old POS-scanners with some of the newer PC-based ones.
I have been informed (by company architects) that the JVM on the iSeries OS does have some performance issues. I do not personally know what these limitations are. In our case the migration has involved allocating an AIX resource, which is supposed to be much better - talk to your IBM rep about whether you just need to purchase the OS license (I just program on the thing, I don't get involved in hardware).
See reponse to question 1. In a larger context, where you're trying to update the browser (or any other resource), this is usually handled by having enterprise licenses - most will have options to allow forced, remote updates.
Some other notes:
You should be able to move to just using .NET, although you may need different hardware/partitions to run the environment. You can talk to DB2 that way, at least. The only benefit Java has there is that it will run on the same OS/hardware as the database.
I've seen a screenscraper application here (it was in VB.NET, but I'm fairly sure the example applies). Screen-scraping was accomplished by getting/putting characters to specific positions on the screens (the equivalent of substring()). That could be just the API we were using - I think I've heard of solutions that were able to read the field names. However, it also relied on the RPG program flow for it's logic, and was otherwise not maintainable.
Most of the RPG programs I've seen and written tend to be a violation of MVC, meaning you can't do anything less than integration testing - the history and architecture of the language itself (and some developers) prefers that everything (file access to screen display) be in one file. This will also make attempting to wrap RPG for calling remotely effectively impossible. IF you've properly seperated everything into Service Programs, you should be able to wrap them up (as the equivalent of a native method call, almost) neatly - unfortunately I haven't seen anything here that didn't tend to rely on one or more tricks that wouldn't hold up for typical Web use (for example, using a file in QTEMP for controlling program execution - the session on the iSeries effectively disappears every time a new page is requested...).
Java as a language tends to promote better seperation of code (note that it can be misused just as badly), as it doesn't have quite the history of RPG. In general, it may be helpful to think of Java as a language where everything is a service program, where all parameters are passed with VALUE set, OPTIONS(*nopass : *omit) is disallowed, CONST is generally recommended, and most parameters are of type DS (datastructure - this is a distinct type in RPG) and passed around by pointer. Module level parameters are frowned upon, if favor of encapsulating everything either in passed datastructures or the service program procedures themselves. STATIC has somewhat different use in Java, making variable global, and is not available inside of procedures.
RPG is quite a bit more simple than Java, generally, and OO-programming is quite a different paradigm. Here are some things that are likely to trip up developers migrating to Java:
Arrays in RPG start at 1. Arrays in Java start at 0.
Java doesn't have 'ouput' parameters, and all primitive types are passed by value (copied). This means that editing an integer won't be visible in calling methods.
Java doesn't have packed/signed encoding, and so translating to/from numbers/strings is more involved. The Date type in Java also has some serious problems (it includes time, sort of), and is far more difficult to meaningfully change to/from a character representation.
It's harder to read/write files in Java, even when using SQL (and forget about using native I/O directly with Java) - this can be mitigated somewhat with a good framework, however.
There are no ENDxx operators in Java, everything uses brackets ({}) to specify the start/end of blocks.
Everything in Java is in freeformat, and there are no columnar specifications of any sort (although procedure signatures are still required). There is no hardlimit on line length, although ~80 characters is still recommended. The tools (the free ones, even) are better, period, and generally far more helpful (although they may take some getting used to for those exposed to SEU). There are also huge, free libraries available for download.
The = sign is not context-sensitive in Java the way it is in RPG, it is always used for assignments. Use the double-equals, == operator for comparisons of values in Java.
Objects (datastructures) cannot be meaningfully compared with == - you will often need to implement a method called equals() instead.
Strings are not mutable, they cannot be changed. All operations performed on strings (either on the class/datastructure itself, or from external libraries) return brand new references. And yes, strings are considered datastructures, not value types, so you can't compare them with == either.
There are no built-in equivalents to the /copy pre-compiler directives. Attempting to implement them is using Java incorrectly. Because these are usually used to deal with 'boilerplate' code (variable definitions or common code), it's better to deal with this in the architecure. Variable(ALL D-specs, actually) definitons will be handled with import or import static statements, while common-code variants are usually handled by a framework, or defining a new class.
I'm sure there are a number of other things out there, let me know if you have any other questions.
Distributing and managing a fat client would be an absolute nightmare.
The ideal solution is a Java based web application hosted on the iSeries. The workstations access your applications through a web browser just like ASP.NET.
I've been using the Grails Framework to modernize and create new applications and it is working wonderfully.
When IBM says you should move to Java/J2EE then you should probably move your applications to web applications like your asp.net web apps. You should probably use a feature rich interface like JSF or GWT.
Web applications don't have to worry about JRE problems as you just need a standard browser.
However I don't know RPG and I don't know the suggested migration strategy.
I am a developer involved in as400 modernization. So far, from my experiences, I can give you my insights.
In addition to Java EE based websites, you can probably go for jax-ws based web services, which provide services for different flat and grid screens.
The clients can consume them in whichever technology they desire. Some lag is there, but the overall usability is good as in the normal web based applications.
I am developing an client-server application where client gets updates every second (lets say 1000 fields) . I also need to draw waveforms from at client side.Server is already existing.
For this type of application which will be better ? GWT with intermediate server or Java Web Start which directly connects to existing server in terms of performance, difficulty to code ?
I don't see that much difference among them. I'd even say that they are separate things. Webstart is how your client will get the app: from some site.
Webstart is a bit easier to mantain, since your client will get it everytime it starts.
Deploying a stand-alone can be a bit harder, depending on your infrastructure.
Performance: just the "download" part of the webstart can be a bit heavier. I thinkg performance is almost the same, after ir began to execute.
Difficulty to code: it's just a matter of experience. Your code in both them will be almost the same, since they'll do the same things.
Mantain / upgrade : easier to mantain and upgrade the Webstart than installing a client on each machine.
Consider using a JFreeChart DynamicTimeSeriesCollection, seen here, distributed via java-web-start. A thousand fields in a scroll pane is possible, but JList or JTable would be considerably more efficient.
If the server already exists, the issue is more about the best way to connect it to the client, than whether or not to use GWT. For example, if you want server-push rather than client-pull for the updates, that changes things somewhat. However, assuming you need to do some vector graphics, and pull information from a server (I'll assume that you can use either JSON or XML to get server information), you could use several different JavaScript toolkits to do this directly, without Java or GWT needed at all.
For this type of application, Dojo would be one fair option. It has fairly good portable vector graphics, it's pure JavaScript and it is finally at a stage where documentation is OK. GWT would be a useful bet if the server didn't already exist, and where you wanted a decent set of controls usable on the client side. But for rich graphics, I'd look at JavaScript options like Dojo, Raphael, or even jQuery. Dojo does support line charts, and that might be a good basis for waveforms.
Some of this depends on the nature of the server. If it uses a different protocol from HTTP, or doesn't really provide easy JSON or XML access, you're probably better looking at a client-server package that does make the bridge between client and server simple.
GWT might be an option here, but it is designed more for robustness than for very fast development. And if you are fitting with an existing protocol, it could be a fair amount of work.
Thinking outside of the box here...
What possible basic approaches could be taken in an effort to create a Flex component that could run Java?
I know I can easily use flex to browse to or launch a Java app, but there are things I can only do if I can run the Java from WITHIN an MXML Component.
I the strictest sense, I know it's not impossible (ie: if you had all the source code for flex and for the jvm), but what's the least impractical means to this end?
Edit:
Lots of people are interested in the reason WHY someone might want to do this. I see it as irrelevant to HOW to do it, but here goes: I have over 100 proprietary pixel-reading windows programs that I could port to Mac in this way, much easier than any other way. But instead of arguing the premises, the winning answer will ignore the reasons why, and focus on the HOW.
Showcase your creativity.
This sounds crazy insane to me. My answer is to not go down this route. It may be a fun technical challenge for fun; but has little practical value that I can see.
Answer the question, Why would you want to run a JVM inside a Flex app?
Also, How would you use a Flex App to browse or launch a Java App? As best I understood, the security sandbox of the browser prevents you from launching other local applications.
I don't believe you are correct about not being able to accomplish certain things you "can only do if I can run the Java from WITHIN an MXML Component". With proper communication set up, you can have the Applet and the SWF simply communicating with each other through an external set of processes.
The easiest way to accomplish this is to "fake it". Load a Java Applet (This should be possible by use of the SWF's ExternalInterface API -- generate the Object tag and add it to the HTML around the swf. To make this even more convincing, use CSS to have to Applet appear "on top" of the swf. ) and have it communicate with the original swf through JavaScript calls. If that is not possible, then it may be possible to have the Java Applet generate some form of pseudo-server which the swf could then communicate with.
If neither of those work, then there is always the SWF bytearray syntax. It would need to load a ByteArray, manipulate the internal data, and then send it... somehow.
A while back I prototyped something like this. I exposed a window / native app via a VNC server and then used an open source VNC client library to connect to the VNC server. It was totally hacky but it worked. Performance was not great but was usable. Here is the Flash VNC client library I used:
http://www.wizhelp.com/flashlight-vnc/index.html
I'm with Flextras, you need to explain why before a reasonable solution can be proposed.
Unreasonable solution:
Implement the jvm in AS3. Read jars in as bytearrays. Pass the bytearrays to you new jvm.
Reasons for unreasonableness:
Implementing even a partial jvm would be at least thousands of man hours of work.
Running a virtual machine inside of Flash's already (relatively) slow vm would be like riding a golf cart that's being towed by a tortoise: either one by itself would be faster.
You can interface between Air & a Java app using merapi (although that's just communication, not actually running the api inside air)