Our build takes a long time, even when nothing has changed. When I run mvn appengine:set_default_version it does a full build, which takes a few minutes.
Is there an easier way to call set_default_version, bypassing the build?
As requested by #Alex :)
I do believe you could build a custom flow to just to call set version. But seems like a complete overkill.
Since you should be changing the default version every once in a while and not on every build (I hope), would't the UI on the cloud Console suffice? You just go to Compute > App Engine > versions and setup the default.
Be advised some people reported issues with the new UI where default version was not changed, so if that fails you might need to use the old app engine console.
Related
I'm not sure if this is a valid question, but what is the least amount of code change before you need to stop the application server, run gradlew publish, gradlew deployCartridges and then start up the application server?
It's not clear to me to what extent can I make code changes.
What would be the preferred development work flow?
First, make sure you have intershop configured correctly for code reloading. You should have these settings set:
# switch auto reload on for all Intershop artifacts
intershop.extensions.CheckSource=true
intershop.queries.CheckSource=true
intershop.pipelines.CheckSource=true
intershop.pagelets.CheckSource=true
intershop.webforms.CheckSource=true
intershop.template.CheckSource=true
intershop.template.CheckSourceModified=true
intershop.template.CompileOnStartup=false
intershop.template.PrintTemplateName=true
intershop.template.PrintTemplateMarker=true
intershop.template.isfilebundle.CheckSource=true
intershop.localization.CheckContent=true
#let intershop run on all cpu cores
intershop.cpu.id=
#dont let session timeout so quickly
intershop.session.TimeOut=60
# switch all preload functionality off
intershop.pipelines.PreloadFromCartridges=
intershop.pipelines.PreloadFromSites=
intershop.pipelets.PreloadFromCartridges=
intershop.webforms.Preload=false
intershop.queries.Preload=false
# Monitor the urlrewrite.properties files for modifications
# and refresh when needed.
intershop.urlrewrite.CheckSource=true
# The time interval in seconds, after which a lookup should be performed
# if CheckSource is "true". 0 means every time (not recommended).
intershop.urlrewrite.CheckSourceInterval=5
These setting are usually in the development.properties file under eserver/server/share/system/config/cluster.
Also make sure that your environment is set to development. The file eserver/server/share/system/config/cluster/environment.properties should have this configured : environment=development. This setting makes intershop load your settings in the development.properties file.
Disable the page cache (in SMC), including the SLDSystem (urlrewriting is cached here). I have fallen into this trap more than I like to admit.
With this setup, you can just edit/save and refresh the browser for isml/pipelines/pagelet,query file,webforms,filebundles,urlrewriting and localization labels. Everything that is not java basically. When it comes to java things get a bit complicated.
For a simple pipelet you can run gradlew publish and it should reload. However, it won't reload other classes that it depends on that has been modified. Sometimes it doesn't reload at all, I have to admit, I don't know why this happens. For new pipelets and changes in the component framework, u always need to compile/restart intershop.
Like Rainer mentioned Jrebel can reload your plain java classes and I can also highly recommend it. However, you would need a license for this.
With code change you mean Java code?
In Development mode you can enable the reloading of pipelet code. There is a special classloader from Intershop for this.
You need to restart the server if you modify any other classes unless you use JRebel, or some other classloader which can detect code modifications.
You of ofcourse have to compile the code with "gradlew publish" for all this.
You also need to restart the server if you made changes in the configuration framework.
While developing you don't need "gradlew deployCartridges" for code changes since the server is reading code from your project directory.
I would like to implement a java application (server application) that can download a new version (.jar file) from a given url, and then update itself at runtime.
What is the best way to do this and is it possible?
I guess that the application can download a new .jar file and start it. But how should I do the handover, e.g. know when the new application is started and then exit. Or is there a better way to do this?
The basic structure of a solution is as follows:
There is a main loop responsible for repeatedly loading the latest version of the app (if required) and launching it.
The application does its thing, but periodically checks the download URL. If it detects a new version it exits back to the launcher.
There are a number of ways you could implement this. For example:
The launcher could be a wrapper script or binary application that starts a new JVM to run the application from a JAR file that gets replaced.
The launcher could be a Java application that creates a classloader for the new JAR, loads an entrypoint class and calls some method on it. If you do it this way, you have to watch for classloader storage leaks, but that's not difficult. (You just need to make sure that no objects with classes loaded from the JAR are reachable after you relaunch.)
The advantages of the external wrapper approach are:
you only need one JAR,
you can replace the entire Java app,
any secondary threads created by the app, etc will go away without special shutdown logic, and
you can also deal with recovery from application crashes, etc.
The second approach requires two JARs, but has the following advantages:
the solution is pure Java and portable,
the changeover will be quicker, and
you can more easily retain state across the restart (modulo leakage issues).
The "best" way depends on your specific requirements.
It should also be noted that:
There are security risks with auto-updating. In general, if the server that provides the updates is compromised, or if the mechanisms for providing the updates are susceptible to attack, then auto-updating can lead to a compromise of the client(s).
Pushing a update to a client that cause damage to the client could have legal risks, and risks to your business' reputation.
If you can find a way to avoid reinventing the wheel, that would be good. See the other answers for suggestions.
I am currently developing a JAVA Linux Daemon and also had the need to implement an auto-update mechanism. I wanted to limit my application to one jar file, and came up with a simple solution:
Pack the updater application in the update itself.
Application: When the application detects a newer version it does the following:
Download update (Zipfile)
Extract Application and ApplicationUpdater (all in the zipfile)
Run updater
ApplicationUpdater: When the updater runs it does the following:
Stop the Application (in my case a daemon via init.d)
Copy the downloaded jar file to overwrite current Application
Start the Application
Cleanup.
Hope it helps someone.
I've recently created update4j which is fully compatible with Java 9's module system.
It will seamlessly start the new version without a restart.
This is a known problem and I recommend against reinventing a wheel - don't write your own hack, just use what other people have already done.
Two situations you need to consider:
App needs to be self-updatable and keep running even during update (server app, embedded apps). Go with OSGi: Bundles or Equinox p2.
App is a desktop app and has an installer. There are many installers with update option. Check installers list.
I've written a Java application that can load plugins at runtime and start using them immediately, inspired by a similar mechanism in jEdit. jEdit is open source so you have the option of looking to see how it works.
The solution uses a custom ClassLoader to load files from the jar. Once they're loaded you can invoke some method from the new jar that will act as its main method. Then the tricky part is making sure you get rid of all references to the old code so that it can be garbage collected. I'm not quite an expert on that part, I've made it work but it wasn't easy.
First way: use tomcat and it's deploy facilities.
Second way: to split application on two parts (functional and update) and let update part replace function part.
Third way: In your server appliction just download new version, then old version releases bound port, then old version runs new version (starts process), then old version sends a request on application port to the new version to delete old version, old version terminates and new version deletes old version. Like this:
This isn't necessarily the best way, but it might work for you.
You can write a bootstrap application (ala the World of Warcraft launcher, if you've played WoW). That bootstrap is responsible for checking for updates.
If an update is available, it will offer it to the user, handle the download, installation, etc.
If the application is up to date, it will allow the user to launch the application
Optionally, you can allow the user to launch the application, even if it isn't up to date
This way you don't have to worry about forcing an exit of your application.
If your application is web based, and if it is important that they have an up to date client, then you can also do version checks while the application runs. You can do them at intervals, while performing normal communication with the server (some or all calls), or both.
For a product I recently worked on, we did version checks upon launch (without a boot strapper app, but before the main window appeared), and during calls to the server. When the client was out of date, we relied on the user to quit manually, but forbid any action against the server.
Please note that I don't know if Java can invoke UI code before you bring up your main window. We were using C#/WPF.
If you build your application using Equinox plugins, you can use the P2 Provisioning System to get a ready-made solution to this problem. This will require the server to restart itself after an update.
I see a security problem when downloading a new jar (etc.), e.g., a man in the middle attack. You always have to sign your downloadable update.
On JAX2015, Adam Bien told about using JGit for updating the binaries.
Sadly I could not find any tutorials.
Source in German.
Adam Bien created the updater see here
I forked it here with some javaFX frontend. I am also working on an automatic signing.
I'm developing an Eclipse plugin that needs to figure out the amount of time that it took for Eclipse to start.
I can get the amount of time since JVM startup in my plugin by using org.eclipse.ui.startup extension point and recording the time by using ManagementFactory.getRuntimeMXBean().getUptime() or eclipse.startTime system property.
However, during startup, Eclipse might ask the user for workspace location and this will be counted in the JVM startup time. As my plugin is trying to measure the non-user-interaction time, this makes the above approach rather useless (unless user has selected a default workspace location but there is no guarantee that this is the case).
Ideally, I would like to know the moment in time when user dismissed the "choose workspace" dialog (or, if user was using default workspace then equivalent moment). Or some other moment as close to that as possible.
I've done a bit of research and there does not seem to be any official extension point for such a thing.
I have a feeling that something like that might be possible with a custom OSGi bundle running at early enough start-level (2). However, I'm not sure if it will actually work:
maybe workspace selection dialog is shown from some Eclipse core plugin, started at start-level 4 like the rest of the plugins?
even if I manage to write such a bundle, do I need to modify Eclipse config.ini to list it there? Or how do I guarantee that it will be started at certain start-level (if it is not a real Eclipse plug-in but a custom bundle)? This article mentions p2.inf but my experiments with it have not been successful yet.
As I do not have much experience with OSGi and Eclipse plugin development, maybe I have missed something rather obvious and the solution is much simpler than what I envisioned?
UPDATE
After a bit more research, I found an early extension point: StartupMonitor service (usually used to customize the splash screen or provide some other sort of startup progress monitor, see here for more details). That could be a possible candidate for my needs, now I just need to figure out, how to make Eclipse aware of it (I suspect I need to add it in config.ini).
Another option I'm considering is to implement a JVM agent and instrument Eclipse IDEApplication class, adding some code snippets that I need. And then add that JVM agent in JVM arguments in eclipse.ini. Could actually be the easiest.
I took the JVM agent approach. Luckily P2 has ability to perform some extra actions via touchpoints -- I can use that to add the JVM agent option automatically at plugin install time and remove it when plugin is uninstalled.
Sample p2.inf file (goes inside META-INF):
instructions.install = \
addJvmArg(jvmArg:-javaagent:${artifact.location}/agent/my-agent.jar);
instructions.install.import = \
org.eclipse.equinox.p2.touchpoint.eclipse.addJvmArg, \
org.eclipse.equinox.p2.touchpoint.eclipse.removeJvmArg
instructions.uninstall = \
removeJvmArg(jvmArg:-javaagent:${artifact.location}/agent/my-agent.jar);
instructions.uninstall.import = \
org.eclipse.equinox.p2.touchpoint.eclipse.addJvmArg, \
org.eclipse.equinox.p2.touchpoint.eclipse.removeJvmArg
(above sample assumes that you have bundled your JVM agent inside the plugin, in agent subdirectory).
I'm one of those guys who step through their code a lot during development. Beginning with version 1.6.4 of the GAE Java development server, the server has been instrumented with calls to a function named Runtime.checkRestricted. This causes two inconveniences when I step through my code:
Whenever I step into a function, the debugger goes into the function Runtime.checkRestricted (for which there is no source code) at least once, often multiple times.
Whenever I step over a function call which has a large call tree underneath, it takes a very long time for the debugger to come back. (That's always a problem in the Eclipse Java debugger, but now it's really bad.)
For me, all this causes a serious drain on productivity. Is there any way to disable this instrumentation, or at least to prevent the debugger from stepping into it? I am using Eclipse with the GAE plugin.
Add a step filter to filter out all step breakpoints you are not interested in. The Eclipse documention provides a guide how to set up step filter.
In your specific case, you will want to add a package filter for com.google.appengine.tools.development.* , as this package and its subpackages contain GAE's Runtime class and RuntimeHelper class. Finally, don't forget to activate the option "Use Step Filters" (Shift + F5).
I am building an application in Java using Netbeans IDE. I am trying to debug some errors in my code. But even when I modify messages passed in the log statements, I do not see a corresponding change in the logged messages. This implies that when execute the code, it probably runs an older version of code & prints the old version of log messages as well.
What is the cause of this error ? & how should I rectify this ?
Thanks for helping..
I had that same problem...closing and reopening netbeans fixed it for me...
By saving the code. I assume, you are have compile-on-save enabled. If not then you have to build it before running it.
Yes you need to enable build-on-save, otherwise GlassFish wouldn't be able to show you the changes, because the new changes have never been deployed. Sometimes, deploying on save bothers a lot. So, what I do is, I don't enable build-on-save and work with tests and thereby run my tests to see the result of the change. When everything seems fine, then I build the app and deploy it on the server for further verifications.
Compile on save must be set.
See the properties of your project.
(Right click, select properties, then select compile).
Another possibility is that you have to redeploy
your project. In such a case I would recommend to
take a look at jRebel.